blob: 4564cf4dfe21fb8b1de17cb61147a7eb44df7e6a [file] [log] [blame]
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtBluetooth module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:GPL-EXCEPT$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include <QtTest/QtTest>
#include <QDebug>
#include <private/qtbluetoothglobal_p.h>
#include <qbluetoothserver.h>
#include <qbluetoothsocket.h>
#include <qbluetoothlocaldevice.h>
QT_USE_NAMESPACE
//same uuid as tests/bttestui
#define TEST_SERVICE_UUID "e8e10f95-1a70-4b27-9ccf-02010264e9c8"
Q_DECLARE_METATYPE(QBluetooth::SecurityFlags)
// Max time to wait for connection
static const int MaxConnectTime = 60 * 1000; // 1 minute in ms
class tst_QBluetoothServer : public QObject
{
Q_OBJECT
public:
tst_QBluetoothServer();
~tst_QBluetoothServer();
private slots:
void initTestCase();
void cleanupTestCase();
void tst_construction();
void tst_receive_data();
void tst_receive();
void setHostMode(const QBluetoothAddress &localAdapter, QBluetoothLocalDevice::HostMode newHostMode);
private:
QBluetoothLocalDevice localDevice;
QBluetoothLocalDevice::HostMode initialHostMode;
};
tst_QBluetoothServer::tst_QBluetoothServer()
{
}
tst_QBluetoothServer::~tst_QBluetoothServer()
{
}
void tst_QBluetoothServer::setHostMode(const QBluetoothAddress &localAdapter,
QBluetoothLocalDevice::HostMode newHostMode)
{
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;
}
int connectTime = 5000; // ms
while (hostModeSpy.count() < 1 && connectTime > 0) {
QTest::qWait(500);
connectTime -= 500;
}
}
void tst_QBluetoothServer::initTestCase()
{
qRegisterMetaType<QBluetooth::SecurityFlags>();
qRegisterMetaType<QBluetoothServer::Error>();
QBluetoothLocalDevice device;
if (!device.isValid())
return;
initialHostMode = device.hostMode();
#ifdef Q_OS_OSX
if (initialHostMode == QBluetoothLocalDevice::HostPoweredOff)
return;
#endif
setHostMode(device.address(), QBluetoothLocalDevice::HostConnectable);
QBluetoothLocalDevice::HostMode hostMode= localDevice.hostMode();
QVERIFY(hostMode != QBluetoothLocalDevice::HostPoweredOff);
}
void tst_QBluetoothServer::cleanupTestCase()
{
QBluetoothLocalDevice device;
setHostMode(device.address(), initialHostMode);
}
void tst_QBluetoothServer::tst_construction()
{
{
QBluetoothServer server(QBluetoothServiceInfo::RfcommProtocol);
QVERIFY(!server.isListening());
QCOMPARE(server.maxPendingConnections(), 1);
QVERIFY(!server.hasPendingConnections());
QVERIFY(server.nextPendingConnection() == 0);
QCOMPARE(server.error(), QBluetoothServer::NoError);
QCOMPARE(server.serverType(), QBluetoothServiceInfo::RfcommProtocol);
}
{
QBluetoothServer server(QBluetoothServiceInfo::L2capProtocol);
QVERIFY(!server.isListening());
QCOMPARE(server.maxPendingConnections(), 1);
QVERIFY(!server.hasPendingConnections());
QVERIFY(server.nextPendingConnection() == 0);
QCOMPARE(server.error(), QBluetoothServer::NoError);
QCOMPARE(server.serverType(), QBluetoothServiceInfo::L2capProtocol);
}
}
void tst_QBluetoothServer::tst_receive_data()
{
QTest::addColumn<QBluetoothLocalDevice::HostMode>("hostmode");
QTest::newRow("offline mode") << QBluetoothLocalDevice::HostPoweredOff;
QTest::newRow("online mode") << QBluetoothLocalDevice::HostConnectable;
}
void tst_QBluetoothServer::tst_receive()
{
QFETCH(QBluetoothLocalDevice::HostMode, hostmode);
QBluetoothLocalDevice localDev;
#ifdef Q_OS_OSX
if (localDev.hostMode() == QBluetoothLocalDevice::HostPoweredOff)
QSKIP("On OS X this test requires Bluetooth adapter ON");
#endif
const QBluetoothAddress address = localDev.address();
bool localDeviceAvailable = localDev.isValid();
if (localDeviceAvailable) {
// setHostMode is noop on OS X and winrt.
setHostMode(address, hostmode);
if (hostmode == QBluetoothLocalDevice::HostPoweredOff) {
#if !defined(Q_OS_OSX) && !QT_CONFIG(winrt_bt)
QCOMPARE(localDevice.hostMode(), hostmode);
#endif
} else {
QVERIFY(localDevice.hostMode() != QBluetoothLocalDevice::HostPoweredOff);
}
}
QBluetoothServer server(QBluetoothServiceInfo::RfcommProtocol);
QSignalSpy errorSpy(&server, SIGNAL(error(QBluetoothServer::Error)));
bool result = server.listen(address, 20); // port == 20
QTest::qWait(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(result);
#if !QT_CONFIG(winrt_bt)
QVERIFY(QBluetoothLocalDevice::allDevices().count());
#endif
QCOMPARE(server.error(), QBluetoothServer::NoError);
QCOMPARE(server.serverAddress(), address);
QCOMPARE(server.serverPort(), quint16(20));
QVERIFY(server.isListening());
QVERIFY(!server.hasPendingConnections());
server.close();
QCOMPARE(server.error(), QBluetoothServer::NoError);
QVERIFY(server.serverAddress() == address || server.serverAddress() == QBluetoothAddress());
QVERIFY(server.serverPort() == 0);
QVERIFY(!server.isListening());
QVERIFY(!server.hasPendingConnections());
}
QTEST_MAIN(tst_QBluetoothServer)
#include "tst_qbluetoothserver.moc"