diff options
59 files changed, 696 insertions, 1979 deletions
diff --git a/client/filepullservice.cpp b/client/filepullservice.cpp deleted file mode 100644 index 1123aac..0000000 --- a/client/filepullservice.cpp +++ /dev/null @@ -1,145 +0,0 @@ -/****************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the Qt Debug Bridge. -** -** $QT_BEGIN_LICENSE:COMM$ -** -** 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 http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** $QT_END_LICENSE$ -** -******************************************************************************/ -#include "filepullservice.h" - -#include "../utils/make_unique.h" -#include "connection.h" -#include "filepullcommon.h" -#include "protocol/services.h" - -#include <QtCore/qbytearray.h> -#include <QtCore/qdebug.h> -#include <QtCore/qfile.h> - -FilePullService::FilePullService(Connection *connection) - : m_connection{connection}, - m_hostPath{}, - m_devicePath{}, - m_sink{nullptr} -{ - -} - -FilePullService::~FilePullService() = default; - -void FilePullService::initialize() -{ - m_connection->createStream(tagBuffer(FilePullTag), [=](Stream *stream) { - this->streamCreated(stream); - }); -} - -bool FilePullService::pull(const QString &devicePath, const QString &hostPath) -{ - if (!m_stream) { - qCritical() << "No valid stream in FilePullService when trying to send"; - return false; - } - m_devicePath = devicePath; - m_hostPath = hostPath; - - StreamPacket packet; - packet << FilePullOpen << m_devicePath; - - return m_stream->write(packet); -} - -void FilePullService::receive(StreamPacket packet) -{ - Q_ASSERT(m_stream); - uint32_t typeValue; - packet >> typeValue; - auto type = toFilePullPacketType(typeValue); - switch (type) { - case FilePullOpened: - qDebug() << "Opened device file for pull"; - openSink(); - break; - case FilePullRead: { - QByteArray fileData; - packet >> fileData; - writeToSink(fileData); - break; - } - case FilePullEnd: - qDebug() << "Pull complete"; - closeSink(); - emit pulled(); - break; - case FilePullError: { - QString errorMessage; - packet >> errorMessage; - qWarning() << "Error on device while pulling:" << errorMessage; - emit error(errorMessage); - m_stream->requestClose(); - break; - } - default: - qFatal("Unsupported FilePullPacketType %d", type); - } -} - -void FilePullService::openSink() -{ - Q_ASSERT(m_stream); - qDebug() << "Opening sink file" << m_hostPath; - m_sink = make_unique<QFile>(m_hostPath); - if (!m_sink->open(QIODevice::WriteOnly)) { - StreamPacket packet; - packet << FilePullError; - m_stream->write(packet); - auto errorMessage = QString{"Could not open sink file \"%1\" on host"}.arg(m_sink->fileName()); - qDebug() << "Error on host:" << errorMessage; - emit error(errorMessage); - m_stream->requestClose(); - } -} - -void FilePullService::writeToSink(const QByteArray &data) -{ - Q_ASSERT(m_stream); - - if (!m_sink->isOpen()) { - qDebug() << "Skipping write to closed sink"; - return; - } - - auto written = m_sink->write(data); - - StreamPacket packet; - - if (written != data.size()) { - qDebug() << "Error in writing to sink"; - packet << FilePullError; - m_stream->write(packet); - m_stream->requestClose(); - } else { - packet << FilePullWasRead; - m_stream->write(packet); - } -} - -void FilePullService::closeSink() -{ - Q_ASSERT(m_stream); - qDebug() << "Closing sink file" << m_sink->fileName(); - m_sink->close(); -} diff --git a/client/filepullservice.h b/client/filepullservice.h deleted file mode 100644 index 3b02fb8..0000000 --- a/client/filepullservice.h +++ /dev/null @@ -1,64 +0,0 @@ -/****************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the Qt Debug Bridge. -** -** $QT_BEGIN_LICENSE:COMM$ -** -** 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 http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** $QT_END_LICENSE$ -** -******************************************************************************/ -#ifndef FILEPULLSERVICE_H -#define FILEPULLSERVICE_H - -class Connection; -#include "service.h" - -#include <QtCore/qstring.h> -QT_BEGIN_NAMESPACE -class QByteArray; -class QFile; -QT_END_NAMESPACE - -#include <memory> - -class FilePullService : public Service -{ - Q_OBJECT -public: - explicit FilePullService(Connection *connection); - ~FilePullService(); - - void initialize() override; - - bool pull(const QString &devicePath, const QString &hostPath); - -signals: - void pulled(); - void error(QString error); - -public slots: - void receive(StreamPacket packet) override; - -private: - void openSink(); - void writeToSink(const QByteArray &data); - void closeSink(); - - Connection *m_connection; - QString m_hostPath; - QString m_devicePath; - std::unique_ptr<QFile> m_sink; -}; - -#endif // FILEPULLSERVICE_H diff --git a/client/filepushservice.cpp b/client/filepushservice.cpp deleted file mode 100644 index 4efa323..0000000 --- a/client/filepushservice.cpp +++ /dev/null @@ -1,137 +0,0 @@ -/****************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the Qt Debug Bridge. -** -** $QT_BEGIN_LICENSE:COMM$ -** -** 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 http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** $QT_END_LICENSE$ -** -******************************************************************************/ -#include "filepushservice.h" - -#include "../utils/make_unique.h" -#include "connection.h" -#include "filepushcommon.h" -#include "protocol/services.h" - -#include <QtCore/qbytearray.h> -#include <QtCore/qdebug.h> -#include <QtCore/qfile.h> - -FilePushService::FilePushService(Connection *connection) - : m_connection{connection}, - m_hostPath{}, - m_devicePath{}, - m_source{nullptr}, - m_transferring{false} -{ - -} - -FilePushService::~FilePushService() -{ - if (m_source && m_source->isOpen()) - m_source->close(); -} - -void FilePushService::initialize() -{ - m_connection->createStream(tagBuffer(FilePushTag), [=](Stream *stream) { - this->streamCreated(stream); - }); -} - -bool FilePushService::push(const QString &hostPath, const QString& devicePath) -{ - if (!m_stream) { - qCritical() << "No valid stream in FilePushService when trying to send"; - return false; - } - m_hostPath = hostPath; - m_devicePath = devicePath; - - StreamPacket packet; - packet << FilePushOpen << m_devicePath; - - return m_stream->write(packet); -} - -void FilePushService::receive(StreamPacket packet) -{ - uint32_t typeValue; - packet >> typeValue; - auto type = toFilePushPacketType(typeValue); - switch (type) { - case FilePushOpened: - qDebug() << "FilePushOpened"; - transferBlock(); - break; - case FilePushWritten: - qDebug() << "FilePushWritten"; - if (m_transferring) - transferBlock(); - else - endTransfer(); - break; - case FilePushError: - m_transferring = false; - qDebug() << "FilePushError"; - emit error("Error on device while pushing"); - break; - default: - qFatal("Unsupported FilePushPacketType %d", type); - } -} - -bool FilePushService::openSource() -{ - m_source = make_unique<QFile>(m_hostPath); - if (!m_source->open(QIODevice::ReadOnly)) { - StreamPacket packet; - packet << FilePushError; - - m_stream->write(packet); - - emit error("Could not open " + m_source->fileName() + " on host"); - return false; - } - return true; -} - -void FilePushService::transferBlock() -{ - if (!m_transferring) { - if (!openSource()) - return; - m_transferring = true; - } - - QByteArray block = m_source->read(fileTransferBlockSize); - m_transferring = !m_source->atEnd(); - - StreamPacket packet; - packet << FilePushWrite << block; - - m_stream->write(packet); -} - -void FilePushService::endTransfer() -{ - StreamPacket packet; - packet << FilePushEnd; - - m_stream->write(packet); - - emit pushed(); -} diff --git a/client/filepushservice.h b/client/filepushservice.h deleted file mode 100644 index 2df1b6a..0000000 --- a/client/filepushservice.h +++ /dev/null @@ -1,65 +0,0 @@ -/****************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the Qt Debug Bridge. -** -** $QT_BEGIN_LICENSE:COMM$ -** -** 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 http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** $QT_END_LICENSE$ -** -******************************************************************************/ -#ifndef FILEPUSHSERVICE_H -#define FILEPUSHSERVICE_H - -class Connection; -#include "service.h" - -#include <QtCore/qstring.h> -QT_BEGIN_NAMESPACE -class QByteArray; -class QFile; -QT_END_NAMESPACE - -#include <memory> - -class FilePushService : public Service -{ - Q_OBJECT -public: - explicit FilePushService(Connection *connection); - ~FilePushService(); - - void initialize() override; - - bool push(const QString &hostPath, const QString &devicePath); - -signals: - void pushed(); - void error(QString error); - -public slots: - void receive(StreamPacket packet) override; - -private: - bool openSource(); - void transferBlock(); - void endTransfer(); - - Connection *m_connection; - QString m_hostPath; - QString m_devicePath; - std::unique_ptr<QFile> m_source; - bool m_transferring; -}; - -#endif // FILEPUSHSERVICE_H diff --git a/client/main.cpp b/client/main.cpp deleted file mode 100644 index e749be1..0000000 --- a/client/main.cpp +++ /dev/null @@ -1,287 +0,0 @@ -/****************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the Qt Debug Bridge. -** -** $QT_BEGIN_LICENSE:COMM$ -** -** 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 http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** $QT_END_LICENSE$ -** -******************************************************************************/ -#include "../libqdb/usb/devicemanagement.h" -#include "../libqdb/usb/usbconnection.h" -#include "../libqdb/protocol/qdbtransport.h" -#include "connection.h" -#include "filepullservice.h" -#include "filepushservice.h" -#include "handshakeservice.h" -#include "interruptsignalhandler.h" -#include "networkmanagercontrol.h" -#include "processservice.h" - -#include <QtCore/qcommandlineparser.h> -#include <QtCore/qcoreapplication.h> -#include <QtCore/qdebug.h> -#include <QtCore/qloggingcategory.h> -#include <QtCore/qregularexpression.h> -#include <QtCore/qtimer.h> -#include <QtDBus/QDBusObjectPath> - -#include <iostream> - -void setupFilePullService(Connection *connection, const QString &sourcePath, const QString &sinkPath) -{ - auto *service = new FilePullService{connection}; - - QObject::connect(QCoreApplication::instance(), &QCoreApplication::aboutToQuit, - service, &QObject::deleteLater); - QObject::connect(service, &FilePullService::pulled, - []() { - std::cout << "File pull finished.\n"; - QCoreApplication::quit(); - }); - QObject::connect(service, &FilePullService::error, []() { - std::cerr << "Error while pulling file.\n"; - QCoreApplication::exit(1); - }); - QObject::connect(service, &Service::initialized, [=]() { - service->pull(sourcePath, sinkPath); - }); - - service->initialize(); -} - -void setupFilePushService(Connection *connection, const QString &sourcePath, const QString &sinkPath) -{ - auto *service = new FilePushService{connection}; - - QObject::connect(QCoreApplication::instance(), &QCoreApplication::aboutToQuit, - service, &QObject::deleteLater); - QObject::connect(service, &FilePushService::pushed, - []() { - std::cout << "File transfer finished.\n"; - QCoreApplication::quit(); - }); - QObject::connect(service, &FilePushService::error, []() { - std::cerr << "Error while pushing file.\n"; - QCoreApplication::exit(1); - }); - QObject::connect(service, &Service::initialized, [=]() { - service->push(sourcePath, sinkPath); - }); - - service->initialize(); -} - -void setupProcessService(Connection *connection, const QString &processName, const QStringList &arguments) -{ - auto *service = new ProcessService{connection}; - - QObject::connect(QCoreApplication::instance(), &QCoreApplication::aboutToQuit, - service, &QObject::deleteLater); - QObject::connect(service, &ProcessService::executed, - [](int exitCode, QProcess::ExitStatus exitStatus, QString output) { - std::printf("Process run, exit code %d (%s):\n%s", - exitCode, - exitStatus == QProcess::NormalExit ? "NormalExit" : "CrashExit", - qUtf8Printable(output)); - QTimer::singleShot(1, []() { QCoreApplication::quit(); }); - }); - QObject::connect(service, &ProcessService::executionError, [](QProcess::ProcessError error) { - std::cerr << "Process not run, error: " << error << std::endl; - QTimer::singleShot(1, []() {QCoreApplication::exit(1); }); - }); - QObject::connect(service, &ProcessService::started, []() { - std::cout << "Process started.\n"; - }); - QObject::connect(service, &ProcessService::readyRead, [=]() { - std::cout << "Process output: " << qUtf8Printable(service->read()) << std::endl; - }); - QObject::connect(service, &Service::initialized, [=]() { - service->execute(processName, arguments); - }); - - service->initialize(); -} - -void configureUsbNetwork(const QString &serial, const QString &macAddress) -{ - qDebug() << "Configuring network for" << serial << "at" << macAddress; - NetworkManagerControl networkManager; - auto deviceResult = networkManager.findNetworkDeviceByMac(macAddress); - if (!deviceResult.isValid()) { - qWarning() << "Could not find network device" << macAddress; - return; - } else { - const auto networkCard = deviceResult.toString(); - if (networkManager.isActivated(networkCard)) { - qDebug() << networkCard << "is activated"; - if (networkManager.isDeviceUsingLinkLocal(networkCard)) { - qInfo() << networkCard << "is already using a link-local IP"; - return; - } - } - if (!networkManager.activateOrCreateConnection(QDBusObjectPath{networkCard}, serial, macAddress)) - qWarning() << "Could not setup network settings for the USB Ethernet interface"; - } -} - -void setupNetworkConfiguration(Connection *connection) -{ - auto *service = new HandshakeService{connection}; - - QObject::connect(QCoreApplication::instance(), &QCoreApplication::aboutToQuit, - service, &QObject::deleteLater); - QObject::connect(service, &HandshakeService::response, - [](QString serial, QString mac, QString ip) { - qDebug() << "Device serial:" << serial; - qDebug() << "Host-side MAC address:" << mac; - qDebug() << "Device IP address:" << ip; - configureUsbNetwork(serial, mac); - QCoreApplication::quit(); - }); - QObject::connect(service, &Service::initialized, [=]() { - service->ask(); - }); - - service->initialize(); -} - -void setupHandshakeService(Connection *connection) -{ - auto *service = new HandshakeService{connection}; - - QObject::connect(QCoreApplication::instance(), &QCoreApplication::aboutToQuit, - service, &QObject::deleteLater); - QObject::connect(service, &HandshakeService::response, - [](QString serial, QString mac, QString ip) { - qDebug() << "Device serial:" << serial; - qDebug() << "Host-side MAC address:" << mac; - qDebug() << "Device IP address:" << ip; - QCoreApplication::quit(); - }); - QObject::connect(service, &Service::initialized, [=]() { - service->ask(); - }); - - service->initialize(); -} - -int main(int argc, char *argv[]) -{ - QCoreApplication app{argc, argv}; - - InterruptSignalHandler signalHandler; - - QCommandLineParser parser; - parser.addHelpOption(); - parser.addOption({"debug-transport", "Print each message that is sent."}); - parser.addOption({"debug-connection", "Show enqueued messages"}); - parser.addOption({{"d", "device"}, "Run the command on <device>. Device is specified with a substring of the device serial number.", "device"}); - parser.addPositionalArgument("command", - "Subcommand of qdb to run. Possible commands are: " - "run, push, pull, devices, handshake, network"); - parser.process(app); - - QString filterRules; - if (!parser.isSet("debug-transport")) - filterRules.append("transport=false\n"); - if (!parser.isSet("debug-connection")) - filterRules.append("connection=false\n"); - QLoggingCategory::setFilterRules(filterRules); - - const QStringList arguments = parser.positionalArguments(); - if (arguments.size() < 1) - parser.showHelp(1); - const QString command = arguments[0]; - - const auto devices = listUsbDevices(); - if (devices.empty()) { - std::cerr << "No QDB devices found.\n"; - return 1; - } - - if (command == "devices") { - std::cout << "USB devices:\n"; - for (const auto &device : devices) { - std::cout << " " << qUtf8Printable(device.serial) << std::endl; - } - return 0; - } - - std::vector<UsbDevice> matchingDevices; - if (parser.isSet("device")) { - QRegularExpression regexp{parser.value("device")}; - - std::copy_if(devices.begin(), devices.end(), std::back_inserter(matchingDevices), [&](const UsbDevice &device) { - return regexp.match(device.serial).hasMatch(); - }); - } else { - matchingDevices = devices; - } - - if (matchingDevices.size() == 0) { - std::cerr << "No device matching \"" << qUtf8Printable(parser.value("device")) << "\" found.\n"; - return 1; - } - if (matchingDevices.size() > 1) { - std::cerr << "Device \"" << qUtf8Printable(parser.value("device")) - << "\" could mean any of the following devices:\n"; - for (const auto &device : devices) - std::cout << " " << qUtf8Printable(device.serial) << std::endl; - return 1; - } - UsbDevice targetDevice = matchingDevices[0]; - qDebug() << "Executing commands for" << targetDevice.serial; - - Connection connection{new QdbTransport{new UsbConnection{targetDevice}}}; - if (!connection.initialize()) { - std::cerr << "Could not initialize connection to \"" << qUtf8Printable(targetDevice.serial) << "\".\n"; - return 1; - } - - QObject::connect(&signalHandler, &InterruptSignalHandler::interrupted, [&]() { - connection.close(); - QCoreApplication::exit(130); - }); - - connection.connect(); - qDebug() << "initialized connection"; - - if (command == "run") { - Q_ASSERT(arguments.size() >= 2); - setupProcessService(&connection, arguments[1], arguments.mid(2)); - } else if (command == "push") { - Q_ASSERT(arguments.size() == 3); - setupFilePushService(&connection, arguments[1], arguments[2]); - } else if (command == "pull") { - Q_ASSERT(arguments.size() == 3); - setupFilePullService(&connection, arguments[1], arguments[2]); - } else if (command == "network") { - if (arguments.size() == 1) { - setupNetworkConfiguration(&connection); - } else { - Q_ASSERT(arguments.size() == 2); - const auto macAddress = arguments[1]; - configureUsbNetwork(QString{"B2Qt device at %1"}.arg(macAddress), macAddress); - QTimer::singleShot(1, []() { QCoreApplication::quit(); }); - } - } else if (command == "handshake") { - setupHandshakeService(&connection); - } else { - std::cerr << "Unrecognized command: " << qUtf8Printable(command) << std::endl; - return 1; - } - - return app.exec(); -} diff --git a/client/processservice.cpp b/client/processservice.cpp deleted file mode 100644 index 8a249c8..0000000 --- a/client/processservice.cpp +++ /dev/null @@ -1,119 +0,0 @@ -/****************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the Qt Debug Bridge. -** -** $QT_BEGIN_LICENSE:COMM$ -** -** 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 http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** $QT_END_LICENSE$ -** -******************************************************************************/ -#include "processservice.h" - -#include "connection.h" -#include "processcommon.h" -#include "protocol/services.h" -#include "stream.h" - -#include <QtCore/qbytearray.h> -#include <QtCore/qdatastream.h> -#include <QtCore/qdebug.h> - -ProcessService::ProcessService(Connection *connection) - : m_connection{connection} -{ - -} - -void ProcessService::initialize() -{ - m_connection->createStream(tagBuffer(ProcessTag), [=](Stream *stream) { - this->streamCreated(stream); - }); -} - -bool ProcessService::execute(const QString &process, const QStringList &arguments) -{ - if (!m_stream) { - qCritical() << "No valid stream in ProcessService when trying to send"; - return false; - } - - StreamPacket packet; - packet << ProcessStart << process << arguments; - - return m_stream->write(packet); -} - -QByteArray ProcessService::read() -{ - if (m_reads.isEmpty()) { - qWarning() << "ProcessService::read(): read from empty queue"; - return QByteArray{}; - } - return m_reads.dequeue(); -} - -qint64 ProcessService::write(const QByteArray &data) -{ - if (!m_stream) { - qCritical() << "No valid stream in ProcessService when trying to write"; - return -1; - } - - StreamPacket packet; - packet << ProcessWrite << data; - - return m_stream->write(packet) ? data.size() : -1; -} - -void ProcessService::receive(StreamPacket packet) -{ - uint32_t typeValue; - packet >> typeValue; - auto type = toProcessPacketType(typeValue); - switch (type) { - case ProcessStarted: { - emit started(); - break; - } - case ProcessRead: { - QByteArray buffer; - packet >> buffer; - m_reads.enqueue(buffer); - emit readyRead(); - break; - } - case ProcessError: { - uint32_t errorValue; - packet >> errorValue; - emit executionError(static_cast<QProcess::ProcessError>(errorValue)); - break; - } - case ProcessFinished: { - int32_t exitCode; - bool normalExit; - QByteArray output; - packet >> exitCode >> normalExit >> output; - - QProcess::ExitStatus exitStatus = normalExit ? QProcess::NormalExit : QProcess::CrashExit; - - emit executed(exitCode, exitStatus, output); - break; - } - default: - Q_ASSERT_X(false, "ProcessService::receive", "Unsupported ProcessPacketType"); - break; - } - -} diff --git a/client/processservice.h b/client/processservice.h deleted file mode 100644 index 78a19e5..0000000 --- a/client/processservice.h +++ /dev/null @@ -1,57 +0,0 @@ -/****************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the Qt Debug Bridge. -** -** $QT_BEGIN_LICENSE:COMM$ -** -** 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 http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** $QT_END_LICENSE$ -** -******************************************************************************/ -#ifndef PROCESSSERVICE_H -#define PROCESSSERVICE_H - -class Connection; -class Stream; -#include "service.h" - -#include <QtCore/qbytearray.h> -#include <QtCore/qprocess.h> -#include <QtCore/qqueue.h> - -class ProcessService : public Service -{ - Q_OBJECT -public: - explicit ProcessService(Connection *connection); - - void initialize() override; - - bool execute(const QString &process, const QStringList &arguments); - QByteArray read(); - qint64 write(const QByteArray &data); -signals: - void executed(int exitCode, QProcess::ExitStatus exitStatus, QByteArray output); - void executionError(QProcess::ProcessError error); - void readyRead(); - void started(); - -public slots: - void receive(StreamPacket packet) override; - -private: - Connection *m_connection; - QQueue<QByteArray> m_reads; -}; - -#endif // PROCESSSERVICE_H diff --git a/libqdb/interruptsignalhandler.cpp b/libqdb/interruptsignalhandler.cpp index 3d2ade6..a47add3 100644 --- a/libqdb/interruptsignalhandler.cpp +++ b/libqdb/interruptsignalhandler.cpp @@ -21,7 +21,7 @@ #include "interruptsignalhandler.h" #ifdef Q_OS_UNIX -#include "../utils/make_unique.h" +#include "libqdb/make_unique.h" #include <QtCore/qdebug.h> #include <QtCore/qsocketnotifier.h> diff --git a/libqdb/libqdb.pro b/libqdb/libqdb.pro index eeacb7e..383d365 100644 --- a/libqdb/libqdb.pro +++ b/libqdb/libqdb.pro @@ -49,4 +49,4 @@ unix { INSTALLS += target } -INCLUDEPATH += $$PWD +INCLUDEPATH += $$PWD/.. diff --git a/utils/make_unique.h b/libqdb/make_unique.h index 3e2d89e..3e2d89e 100644 --- a/utils/make_unique.h +++ b/libqdb/make_unique.h diff --git a/libqdb/protocol/protocol.h b/libqdb/protocol/protocol.h index c0ae09b..4f50ab2 100644 --- a/libqdb/protocol/protocol.h +++ b/libqdb/protocol/protocol.h @@ -23,9 +23,6 @@ #include <cstdint> -const uint8_t qdbUsbClassId = 0xff; -const uint8_t qdbUsbSubclassId = 0x52; -const uint8_t qdbUsbProtocolId = 0x1; const int qdbHeaderSize = 4*sizeof(uint32_t); const int qdbMessageSize = 16*1024; const int qdbMaxPayloadSize = qdbMessageSize - qdbHeaderSize; diff --git a/libqdb/protocol/qdbtransport.h b/libqdb/protocol/qdbtransport.h index de5720a..d98e1ae 100644 --- a/libqdb/protocol/qdbtransport.h +++ b/libqdb/protocol/qdbtransport.h @@ -21,7 +21,7 @@ #ifndef QDBTRANSPORT_H #define QDBTRANSPORT_H -#include "protocol/qdbmessage.h" +#include "qdbmessage.h" #include <QtCore/qobject.h> QT_BEGIN_NAMESPACE diff --git a/libqdb/protocol/services.h b/libqdb/protocol/services.h index 0c02004..b25b928 100644 --- a/libqdb/protocol/services.h +++ b/libqdb/protocol/services.h @@ -29,14 +29,9 @@ enum ServiceTag : uint32_t { EchoTag = 1, - ProcessTag, - FilePushTag, - FilePullTag, HandshakeTag, }; -const int fileTransferBlockSize = 4096; // in bytes - inline QByteArray tagBuffer(ServiceTag tag, int padding = 0) { diff --git a/libqdb/qdbconstants.h b/libqdb/qdbconstants.h new file mode 100644 index 0000000..6da5c95 --- /dev/null +++ b/libqdb/qdbconstants.h @@ -0,0 +1,32 @@ +/****************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Debug Bridge. +** +** $QT_BEGIN_LICENSE:COMM$ +** +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** $QT_END_LICENSE$ +** +******************************************************************************/ +#ifndef QDBCONSTANTS_H +#define QDBCONSTANTS_H + +#include <cstdint> + +const char * const qdbSocketName = "qdb.socket"; + +const uint8_t qdbUsbClassId = 0xff; +const uint8_t qdbUsbSubclassId = 0x52; +const uint8_t qdbUsbProtocolId = 0x1; + +#endif // QDBCONSTANTS_H diff --git a/utils/scopeguard.h b/libqdb/scopeguard.h index 89ff695..89ff695 100644 --- a/utils/scopeguard.h +++ b/libqdb/scopeguard.h diff --git a/libqdb/usb/devicemanagement.cpp b/libqdb/usb/devicemanagement.cpp index 3f67cd6..8e7ad38 100644 --- a/libqdb/usb/devicemanagement.cpp +++ b/libqdb/usb/devicemanagement.cpp @@ -19,10 +19,10 @@ ** ******************************************************************************/ #include "devicemanagement.h" -#include "protocol/protocol.h" +#include "scopeguard.h" #include "usbcommon.h" #include "usbconnection.h" -#include "../utils/scopeguard.h" +#include "qdbconstants.h" #include <QtCore/qdebug.h> diff --git a/libqdb/usb/usbconnection.cpp b/libqdb/usb/usbconnection.cpp index 9f99dc3..f159d19 100644 --- a/libqdb/usb/usbconnection.cpp +++ b/libqdb/usb/usbconnection.cpp @@ -20,9 +20,9 @@ ******************************************************************************/ #include "usbconnection.h" -#include "../utils/make_unique.h" -#include "../utils/scopeguard.h" +#include "make_unique.h" #include "protocol/protocol.h" +#include "scopeguard.h" #include "usbcommon.h" #include "usbconnectionreader.h" diff --git a/libqdb/usb/usbconnection.h b/libqdb/usb/usbconnection.h index d78253f..9f2bd95 100644 --- a/libqdb/usb/usbconnection.h +++ b/libqdb/usb/usbconnection.h @@ -21,7 +21,7 @@ #ifndef USBMANAGER_H #define USBMANAGER_H -#include "libqdb_global.h" +#include "../libqdb_global.h" #include "usbdevice.h" class UsbConnectionReader; @@ -5,10 +5,10 @@ load(configure) SUBDIRS += \ libqdb \ - client \ - tests + qdb \ + tests \ -client.depends += libqdb +qdb.depends += libqdb tests.depends += libqdb unix { diff --git a/qdb/client/client.cpp b/qdb/client/client.cpp new file mode 100644 index 0000000..cbb698f --- /dev/null +++ b/qdb/client/client.cpp @@ -0,0 +1,55 @@ +/****************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Debug Bridge. +** +** $QT_BEGIN_LICENSE:COMM$ +** +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** $QT_END_LICENSE$ +** +******************************************************************************/ +#include "client.h" + +#include "libqdb/qdbconstants.h" + +#include <QtCore/qcoreapplication.h> +#include <QtCore/qjsondocument.h> +#include <QtCore/qjsonobject.h> +#include <QtCore/qtimer.h> +#include <QtNetwork/qlocalsocket.h> + +#include <iostream> + +int askDevices(QCoreApplication &app) +{ + QLocalSocket socket; + socket.connectToServer(qdbSocketName); + if (!socket.waitForConnected()) { + std::cerr << "Could not connect to QDB host server\n"; + return 1; + } + + socket.write("{\"request\":\"devices\"}"); + if (!socket.waitForReadyRead()) { + std::cerr << "Could not read response from QDB host server\n"; + return 1; + } + const auto response = socket.readLine(); + const auto document = QJsonDocument::fromJson(response); + + std::cout << "Response: " << document.toJson().data() << std::endl; + + QTimer::singleShot(0, &app, &QCoreApplication::quit); + + return app.exec(); +} diff --git a/qdb/client/client.h b/qdb/client/client.h new file mode 100644 index 0000000..814728d --- /dev/null +++ b/qdb/client/client.h @@ -0,0 +1,28 @@ +/****************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Debug Bridge. +** +** $QT_BEGIN_LICENSE:COMM$ +** +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** $QT_END_LICENSE$ +** +******************************************************************************/ +#ifndef CLIENT_H +#define CLIENT_H + +class QCoreApplication; + +int askDevices(QCoreApplication &app); + +#endif // CLIENT_H diff --git a/qdb/main.cpp b/qdb/main.cpp new file mode 100644 index 0000000..e8645fc --- /dev/null +++ b/qdb/main.cpp @@ -0,0 +1,56 @@ +/****************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Debug Bridge. +** +** $QT_BEGIN_LICENSE:COMM$ +** +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** $QT_END_LICENSE$ +** +******************************************************************************/ +#include "client/client.h" +#include "libqdb/interruptsignalhandler.h" +#include "server/hostserver.h" + +#include <QtCore/qcommandlineparser.h> +#include <QtCore/qcoreapplication.h> + +#include <iostream> + +int main(int argc, char *argv[]) +{ + QCoreApplication app{argc, argv}; + + QCommandLineParser parser; + parser.addHelpOption(); + parser.addOption({"debug-transport", "Print each message that is sent. (Only server process)"}); + parser.addOption({"debug-connection", "Show enqueued messages. (Only server process)"}); + parser.addPositionalArgument("command", + "Subcommand of qdb to run. Possible commands are: " + "devices, server"); + parser.process(app); + + const QStringList arguments = parser.positionalArguments(); + if (arguments.size() < 1) + parser.showHelp(1); + const QString command = arguments[0]; + + if (command == "devices") { + return askDevices(app); + } else if (command == "server") { + return hostServer(app, parser); + } else { + std::cerr << "Unrecognized command: " << qUtf8Printable(command) << std::endl; + return 1; + } +} diff --git a/client/client.pro b/qdb/qdb.pro index 0bae2f4..48f3a97 100644 --- a/client/client.pro +++ b/qdb/qdb.pro @@ -1,5 +1,5 @@ QT -= gui -QT += dbus +QT += dbus network CONFIG += c++11 @@ -10,27 +10,27 @@ CONFIG -= app_bundle TEMPLATE = app HEADERS += \ - connection.h \ - echoservice.h \ - filepullservice.h \ - filepushservice.h \ - handshakeservice.h \ - networkmanagercontrol.h \ - processservice.h \ - service.h \ + client/client.h \ + server/connection.h \ + server/deviceinformationfetcher.h \ + server/echoservice.h \ + server/handshakeservice.h \ + server/hostserver.h \ + server/networkmanagercontrol.h \ + server/service.h \ SOURCES += \ - connection.cpp \ - echoservice.cpp \ - filepullservice.cpp \ - filepushservice.cpp \ - handshakeservice.cpp \ + client/client.cpp \ main.cpp \ - networkmanagercontrol.cpp \ - processservice.cpp \ - service.cpp \ + server/connection.cpp \ + server/deviceinformationfetcher.cpp \ + server/echoservice.cpp \ + server/handshakeservice.cpp \ + server/hostserver.cpp \ + server/networkmanagercontrol.cpp \ + server/service.cpp \ -INCLUDEPATH += $$PWD/../libqdb +INCLUDEPATH += $$PWD/../ unix { LIBS = -L$$OUT_PWD/../libqdb -lqdb @@ -40,12 +40,11 @@ unix { } win32 { - -CONFIG(debug, debug|release) { - LIBQDBDIR = $$OUT_PWD/../libqdb/debug -} else { - LIBQDBDIR = $$OUT_PWD/../libqdb/release -} + CONFIG(debug, debug|release) { + LIBQDBDIR = $$OUT_PWD/../libqdb/debug + } else { + LIBQDBDIR = $$OUT_PWD/../libqdb/release + } LIBS = -L$$LIBQDBDIR -lqdb diff --git a/client/connection.cpp b/qdb/server/connection.cpp index 747fcc2..63b57b3 100644 --- a/client/connection.cpp +++ b/qdb/server/connection.cpp @@ -20,9 +20,9 @@ ******************************************************************************/ #include "connection.h" -#include "../utils/make_unique.h" -#include "protocol/protocol.h" -#include "protocol/qdbtransport.h" +#include "libqdb/make_unique.h" +#include "libqdb/protocol/protocol.h" +#include "libqdb/protocol/qdbtransport.h" #include "service.h" #include <QtCore/qdebug.h> diff --git a/client/connection.h b/qdb/server/connection.h index 1f3ed62..e77d358 100644 --- a/client/connection.h +++ b/qdb/server/connection.h @@ -21,7 +21,7 @@ #ifndef CONNECTION_H #define CONNECTION_H -#include "abstractconnection.h" +#include "libqdb/abstractconnection.h" class Service; class QdbMessage; class QdbTransport; diff --git a/qdb/server/deviceinformationfetcher.cpp b/qdb/server/deviceinformationfetcher.cpp new file mode 100644 index 0000000..b281652 --- /dev/null +++ b/qdb/server/deviceinformationfetcher.cpp @@ -0,0 +1,75 @@ +/****************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Debug Bridge. +** +** $QT_BEGIN_LICENSE:COMM$ +** +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** $QT_END_LICENSE$ +** +******************************************************************************/ +#include "deviceinformationfetcher.h" + +#include "connection.h" +#include "handshakeservice.h" +#include "libqdb/usb/usbconnection.h" +#include "libqdb/protocol/qdbtransport.h" + +#include <QtCore/qdebug.h> + +DeviceInformationFetcher::DeviceInformationFetcher(UsbDevice device) + : m_connection{new Connection{new QdbTransport{new UsbConnection{device}}}}, + m_connected{false} +{ + connect(this, &DeviceInformationFetcher::fetched, m_connection, &Connection::close); + connect(this, &DeviceInformationFetcher::fetched, m_connection, &QObject::deleteLater); + + if (!m_connection->initialize()) { + qCritical() << "DeviceInformationFetcher: Could not initialize connection to" << device.serial; + return; + } + + m_connection->connect(); + m_connected = true; + qDebug() << "Initialized connection to" << device.serial; +} + +void DeviceInformationFetcher::fetch() +{ + if (!m_connected) { + qDebug() << "Not fetching device information due to no connection"; + emit fetched(DeviceInformation{"", "", ""}); + return; + } + + auto *service = new HandshakeService{m_connection}; + + connect(this, &DeviceInformationFetcher::fetched, + service, &QObject::deleteLater); + connect(service, &HandshakeService::response, + this, &DeviceInformationFetcher::handshakeResponse); + connect(service, &Service::initialized, [=]() { + service->ask(); + }); + + service->initialize(); +} + +void DeviceInformationFetcher::handshakeResponse(QString serial, QString hostMac, QString ipAddress) +{ + qDebug() << "Handshakeservice responded:"; + qDebug() << " Device serial:" << serial; + qDebug() << " Host-side MAC address:" << hostMac; + qDebug() << " Device IP address:" << ipAddress; + emit fetched(DeviceInformation{serial, hostMac, ipAddress}); +} diff --git a/qdbd/filepullexecutor.h b/qdb/server/deviceinformationfetcher.h index 7f33583..43d15cb 100644 --- a/qdbd/filepullexecutor.h +++ b/qdb/server/deviceinformationfetcher.h @@ -18,35 +18,39 @@ ** $QT_END_LICENSE$ ** ******************************************************************************/ -#ifndef FILEPULLEXECUTOR_H -#define FILEPULLEXECUTOR_H +#ifndef DEVICEINFORMATIONFETCHER_H +#define DEVICEINFORMATIONFETCHER_H -#include "executor.h" -class Stream; +#include "connection.h" +#include "libqdb/usb/usbdevice.h" -QT_BEGIN_NAMESPACE -class QByteArray; -class QFile; -QT_END_NAMESPACE +#include <QtCore/qobject.h> -#include <memory> +struct DeviceInformation +{ + QString serial; + QString hostMac; + QString ipAddress; +}; -class FilePullExecutor : public Executor +class DeviceInformationFetcher : public QObject { + Q_OBJECT public: - explicit FilePullExecutor(Stream *stream); + explicit DeviceInformationFetcher(UsbDevice device); + +signals: + void fetched(DeviceInformation deviceInfo); public slots: - void receive(StreamPacket packet) override; + void fetch(); -private: - bool openSource(const QString &path); - void transferBlock(); - void closeSource(); +private slots: + void handshakeResponse(QString serial, QString hostMac, QString ipAddress); - Stream* m_stream; - std::unique_ptr<QFile> m_source; - bool m_transferring; +private: + Connection *m_connection; // owned by this class, deletion set up in constructor + bool m_connected; }; -#endif // FILEPULLEXECUTOR_H +#endif // DEVICEINFORMATIONFETCHER_H diff --git a/client/echoservice.cpp b/qdb/server/echoservice.cpp index 4767951..b69a7c2 100644 --- a/client/echoservice.cpp +++ b/qdb/server/echoservice.cpp @@ -21,8 +21,8 @@ #include "echoservice.h" #include "connection.h" -#include "protocol/services.h" -#include "stream.h" +#include "libqdb/protocol/services.h" +#include "libqdb/stream.h" #include <QtCore/qdebug.h> diff --git a/client/echoservice.h b/qdb/server/echoservice.h index 31b1370..31b1370 100644 --- a/client/echoservice.h +++ b/qdb/server/echoservice.h diff --git a/client/handshakeservice.cpp b/qdb/server/handshakeservice.cpp index 85498e9..5d687be 100644 --- a/client/handshakeservice.cpp +++ b/qdb/server/handshakeservice.cpp @@ -21,8 +21,8 @@ #include "handshakeservice.h" #include "connection.h" -#include "protocol/services.h" -#include "stream.h" +#include "libqdb/protocol/services.h" +#include "libqdb/stream.h" #include <QtCore/qdebug.h> diff --git a/client/handshakeservice.h b/qdb/server/handshakeservice.h index e784aa7..e784aa7 100644 --- a/client/handshakeservice.h +++ b/qdb/server/handshakeservice.h diff --git a/qdb/server/hostserver.cpp b/qdb/server/hostserver.cpp new file mode 100644 index 0000000..d4da0c5 --- /dev/null +++ b/qdb/server/hostserver.cpp @@ -0,0 +1,213 @@ +/****************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Debug Bridge. +** +** $QT_BEGIN_LICENSE:COMM$ +** +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** $QT_END_LICENSE$ +** +******************************************************************************/ +#include "hostserver.h" + +#include "libqdb/interruptsignalhandler.h" +#include "libqdb/qdbconstants.h" +#include "networkmanagercontrol.h" + +#include <QtCore/qcoreapplication.h> +#include <QtCore/qcommandlineparser.h> +#include <QtCore/qdir.h> +#include <QtCore/qfile.h> +#include <QtCore/qloggingcategory.h> +#include <QtCore/qjsonarray.h> +#include <QtCore/qjsondocument.h> +#include <QtCore/qjsonobject.h> +#include <QtCore/qstring.h> +#include <QtCore/qtimer.h> +#include <QtDBus/QDBusObjectPath> +#include <QtNetwork/qlocalserver.h> +#include <QtNetwork/qlocalsocket.h> + +void configureUsbNetwork(const QString &serial, const QString &macAddress) +{ + qDebug() << "Configuring network for" << serial << "at" << macAddress; + NetworkManagerControl networkManager; + auto deviceResult = networkManager.findNetworkDeviceByMac(macAddress); + if (!deviceResult.isValid()) { + qWarning() << "Could not find network device" << macAddress; + return; + } else { + const auto networkCard = deviceResult.toString(); + if (networkManager.isActivated(networkCard)) { + qDebug() << networkCard << "is activated"; + if (networkManager.isDeviceUsingLinkLocal(networkCard)) { + qInfo() << networkCard << "is already using a link-local IP"; + return; + } + } + if (!networkManager.activateOrCreateConnection(QDBusObjectPath{networkCard}, serial, macAddress)) + qWarning() << "Could not setup network settings for the USB Ethernet interface"; + } +} + +int hostServer(QCoreApplication &app, const QCommandLineParser &parser) +{ + QString filterRules; + if (!parser.isSet("debug-transport")) + filterRules.append("transport=false\n"); + if (!parser.isSet("debug-connection")) + filterRules.append("connection=false\n"); + QLoggingCategory::setFilterRules(filterRules); + + InterruptSignalHandler signalHandler; + HostServer hostServer; + QObject::connect(&signalHandler, &InterruptSignalHandler::interrupted, &hostServer, &HostServer::close); + QObject::connect(&hostServer, &HostServer::closed, &app, &QCoreApplication::quit); + QTimer::singleShot(0, &hostServer, &HostServer::listen); + + return app.exec(); +} + +HostServer::HostServer(QObject *parent) + : QObject{parent}, + m_localServer{}, + m_client{nullptr}, + m_devices{}, + m_deviceInfos{}, + m_fetchIndex{-1} +{ + +} + +void HostServer::listen() +{ +#ifdef Q_OS_UNIX + QFile::remove(QDir::tempPath() + qdbSocketName); +#endif + if (!m_localServer.listen(qdbSocketName)) { + qCritical() << "Could not start listening with QLocalServer: " + << m_localServer.errorString(); + close(); + return; + } + connect(&m_localServer, &QLocalServer::newConnection, this, &HostServer::handleConnection); + qDebug() << "Host server started listening."; +} + +void HostServer::close() +{ + m_localServer.close(); + emit closed(); +} + +void HostServer::handleConnection() +{ + Q_ASSERT_X(!m_client, "HostServer::handleConnection", "concurrent connections are not implemented"); // TODO + m_client = m_localServer.nextPendingConnection(); + if (!m_client) { + qCritical() << "Did not get a connection from client"; + close(); + return; + } + QObject::connect(m_client, &QLocalSocket::disconnected, this, &HostServer::handleDisconnection); + QObject::connect(m_client, &QIODevice::readyRead, this, &HostServer::handleRequest); +} + +void HostServer::handleDisconnection() +{ + m_client->deleteLater(); + m_client = nullptr; +} + +void HostServer::handleDeviceInformation(DeviceInformation deviceInfo) +{ + m_deviceInfos.push_back(deviceInfo); + ++m_fetchIndex; + + if (m_fetchIndex < m_devices.size()) + fetchDeviceInformation(); + else + finishFetching(); +} + +void HostServer::handleRequest() +{ + const auto requestBytes = m_client->readLine(1000); + const auto request = QJsonDocument::fromJson(requestBytes); + const auto requestObject = request.object(); + + if (requestObject["request"] == "devices") { + startFetching(); + } else { + qWarning() << "Got invalid request from client:" << requestBytes; + m_client->disconnectFromServer(); + } +} + +void HostServer::startFetching() +{ + m_devices = listUsbDevices(); + + qDebug() << "USB devices:"; + for (const auto &device : m_devices) { + qDebug() << " " << device.serial; + } + + Q_ASSERT_X(m_fetchIndex == -1, "HostServer::startFetching", "handling concurrent requests not implemented"); // TODO + m_fetchIndex = 0; + m_deviceInfos.clear(); + if (m_devices.empty()) + finishFetching(); + else + fetchDeviceInformation(); +} + +void HostServer::finishFetching() +{ + m_fetchIndex = -1; + + qDebug() << "Configuring network for all devices"; + for (const auto deviceInfo : m_deviceInfos) + configureUsbNetwork(deviceInfo.serial, deviceInfo.hostMac); + + QJsonObject obj; + QJsonArray infoArray; + for (const auto deviceInfo : m_deviceInfos) { + QJsonObject info; + info["serial"] = deviceInfo.serial; + info["hostMac"] = deviceInfo.hostMac; + info["ipAddress"] = deviceInfo.ipAddress; + infoArray << info; + } + obj["devices"] = infoArray; + const QByteArray response = QJsonDocument{obj}.toJson(QJsonDocument::Compact); + + if (!m_client || !m_client->isWritable()) { + qWarning() << "Could not reply to the client"; + return; + } + m_client->write(response); + m_client->waitForBytesWritten(); + m_client->disconnectFromServer(); + qDebug() << "Replied to the client"; +} + +void HostServer::fetchDeviceInformation() +{ + qDebug() << "Fetching device information for" << m_fetchIndex; + auto *fetcher = new DeviceInformationFetcher{m_devices[m_fetchIndex]}; + connect(fetcher, &DeviceInformationFetcher::fetched, fetcher, &QObject::deleteLater); + connect(fetcher, &DeviceInformationFetcher::fetched, this, &HostServer::handleDeviceInformation); + + fetcher->fetch(); +} diff --git a/qdb/server/hostserver.h b/qdb/server/hostserver.h new file mode 100644 index 0000000..c01c9ba --- /dev/null +++ b/qdb/server/hostserver.h @@ -0,0 +1,65 @@ +/****************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Debug Bridge. +** +** $QT_BEGIN_LICENSE:COMM$ +** +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** $QT_END_LICENSE$ +** +******************************************************************************/ +#ifndef HOSTSERVER_H +#define HOSTSERVER_H + +#include "libqdb/usb/devicemanagement.h" +#include "deviceinformationfetcher.h" + +#include <QtCore/qobject.h> +#include <QtNetwork/qlocalserver.h> +class QCoreApplication; +class QCommandLineParser; + +int hostServer(QCoreApplication &app, const QCommandLineParser &parser); + +class HostServer : public QObject +{ + Q_OBJECT +public: + explicit HostServer(QObject *parent = nullptr); + void listen(); + +signals: + void closed(); + +public slots: + void close(); + +private slots: + void handleConnection(); + void handleDisconnection(); + void handleDeviceInformation(DeviceInformation deviceInfo); + void handleRequest(); + +private: + void startFetching(); + void finishFetching(); + void fetchDeviceInformation(); + + QLocalServer m_localServer; + QLocalSocket *m_client; // owned by this class, deleted in handleDisconnection() + std::vector<UsbDevice> m_devices; + std::vector<DeviceInformation> m_deviceInfos; + int m_fetchIndex; +}; + +#endif // HOSTSERVER_H diff --git a/client/networkmanagercontrol.cpp b/qdb/server/networkmanagercontrol.cpp index 09edae5..09edae5 100644 --- a/client/networkmanagercontrol.cpp +++ b/qdb/server/networkmanagercontrol.cpp diff --git a/client/networkmanagercontrol.h b/qdb/server/networkmanagercontrol.h index 3923e9d..3923e9d 100644 --- a/client/networkmanagercontrol.h +++ b/qdb/server/networkmanagercontrol.h diff --git a/client/service.cpp b/qdb/server/service.cpp index 55e9f4c..b381550 100644 --- a/client/service.cpp +++ b/qdb/server/service.cpp @@ -20,7 +20,7 @@ ******************************************************************************/ #include "service.h" -#include "stream.h" +#include "libqdb/stream.h" #include <QtCore/qdebug.h> diff --git a/client/service.h b/qdb/server/service.h index 7f8f743..43af338 100644 --- a/client/service.h +++ b/qdb/server/service.h @@ -22,7 +22,7 @@ #define SERVICE_H class Stream; -#include "streampacket.h" +#include "libqdb/streampacket.h" #include <QtCore/qobject.h> diff --git a/qdbd/createexecutor.cpp b/qdbd/createexecutor.cpp index 06dc0c3..d11eb4c 100644 --- a/qdbd/createexecutor.cpp +++ b/qdbd/createexecutor.cpp @@ -20,13 +20,10 @@ ******************************************************************************/ #include "createexecutor.h" -#include "../utils/make_unique.h" #include "echoexecutor.h" -#include "filepullexecutor.h" -#include "filepushexecutor.h" #include "handshakeexecutor.h" -#include "processexecutor.h" -#include "protocol/services.h" +#include "libqdb/make_unique.h" +#include "libqdb/protocol/services.h" #include <QtCore/qdatastream.h> #include <QtCore/qfile.h> @@ -40,12 +37,6 @@ std::unique_ptr<Executor> createExecutor(Stream *stream, const QByteArray &tagBu switch (static_cast<ServiceTag>(tag)) { case EchoTag: return make_unique<EchoExecutor>(stream); - case ProcessTag: - return make_unique<ProcessExecutor>(stream); - case FilePushTag: - return make_unique<FilePushExecutor>(stream); - case FilePullTag: - return make_unique<FilePullExecutor>(stream); case HandshakeTag: return make_unique<HandshakeExecutor>(stream); default: diff --git a/qdbd/echoexecutor.cpp b/qdbd/echoexecutor.cpp index 8c6788f..325df7c 100644 --- a/qdbd/echoexecutor.cpp +++ b/qdbd/echoexecutor.cpp @@ -20,7 +20,7 @@ ******************************************************************************/ #include "echoexecutor.h" -#include "stream.h" +#include "libqdb/stream.h" #include <QtCore/qdebug.h> diff --git a/qdbd/executor.h b/qdbd/executor.h index 4dde463..cd4431b 100644 --- a/qdbd/executor.h +++ b/qdbd/executor.h @@ -22,7 +22,7 @@ #define EXECUTOR_H class Stream; -#include "streampacket.h" +#include "libqdb/streampacket.h" #include <QtCore/qobject.h> diff --git a/qdbd/filepullexecutor.cpp b/qdbd/filepullexecutor.cpp deleted file mode 100644 index ad581a8..0000000 --- a/qdbd/filepullexecutor.cpp +++ /dev/null @@ -1,108 +0,0 @@ -/****************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the Qt Debug Bridge. -** -** $QT_BEGIN_LICENSE:COMM$ -** -** 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 http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** $QT_END_LICENSE$ -** -******************************************************************************/ -#include "filepullexecutor.h" - -#include "../utils/make_unique.h" -#include "filepullcommon.h" -#include "protocol/services.h" -#include "stream.h" - -#include <QtCore/qdatastream.h> -#include <QtCore/qdebug.h> -#include <QtCore/qfile.h> - -FilePullExecutor::FilePullExecutor(Stream *stream) - : m_stream{stream}, - m_source{nullptr}, - m_transferring{false} -{ - if (m_stream) - connect(m_stream, &Stream::packetAvailable, this, &Executor::receive); -} - -void FilePullExecutor::receive(StreamPacket packet) -{ - uint32_t typeValue; - packet >> typeValue; - auto type = toFilePullPacketType(typeValue); - switch (type) { - case FilePullOpen: { - QString sourcePath; - packet >> sourcePath; - if (openSource(sourcePath)) - transferBlock(); - break; - } - case FilePullWasRead: - qDebug() << "File pull read acknowledged."; - if (m_transferring) - transferBlock(); - else - closeSource(); - break; - case FilePullError: - qDebug() << "FilePullError from host"; - closeSource(); - break; - default: - qFatal("Unsupported FilePushPacketType %d in ProcessExecutor::receive", type); - } -} - -bool FilePullExecutor::openSource(const QString &path) -{ - qDebug() << "Opening source file" << path; - m_source = make_unique<QFile>(path); - bool opened = m_source->open(QIODevice::ReadOnly); - - StreamPacket packet; - - if (!opened) { - packet << FilePullError - << QString{"Could not open \"%1\" on device"}.arg(m_source->fileName()); - } else { - packet << FilePullOpened; - } - - return m_stream->write(packet) && opened; -} - -void FilePullExecutor::transferBlock() -{ - QByteArray block = m_source->read(fileTransferBlockSize); - m_transferring = !m_source->atEnd(); - - StreamPacket packet; - packet << FilePullRead << block; - - m_stream->write(packet); -} - -void FilePullExecutor::closeSource() -{ - qDebug() << "Closing source file" << m_source->fileName(); - m_source->close(); - - StreamPacket packet; - packet << FilePullEnd; - - m_stream->write(packet); -} diff --git a/qdbd/filepushexecutor.cpp b/qdbd/filepushexecutor.cpp deleted file mode 100644 index a208a11..0000000 --- a/qdbd/filepushexecutor.cpp +++ /dev/null @@ -1,102 +0,0 @@ -/****************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the Qt Debug Bridge. -** -** $QT_BEGIN_LICENSE:COMM$ -** -** 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 http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** $QT_END_LICENSE$ -** -******************************************************************************/ -#include "filepushexecutor.h" - -#include "../utils/make_unique.h" -#include "filepushcommon.h" -#include "stream.h" - -#include <QtCore/qdatastream.h> -#include <QtCore/qdebug.h> -#include <QtCore/qfile.h> - -FilePushExecutor::FilePushExecutor(Stream *stream) - : m_stream{stream}, - m_sink{nullptr} -{ - if (m_stream) - connect(m_stream, &Stream::packetAvailable, this, &Executor::receive); -} - -void FilePushExecutor::receive(StreamPacket packet) -{ - uint32_t typeValue; - packet >> typeValue; - auto type = toFilePushPacketType(typeValue); - switch (type) { - case FilePushOpen: { - QString sinkPath; - packet >> sinkPath; - openSink(sinkPath); - break; - } - case FilePushWrite: { - QByteArray fileData; - packet >> fileData; - writeToSink(fileData); - break; - } - case FilePushEnd: - closeSink(); - break; - case FilePushError: - qDebug() << "FilePushError from host"; - if (m_sink) - m_sink->remove(); - break; - default: - qFatal("Unsupported FilePushPacketType %d in ProcessExecutor::receive", type); - } -} - -void FilePushExecutor::openSink(const QString &path) -{ - qDebug() << "Opening sink file" << path; - m_sink = make_unique<QFile>(path); - StreamPacket packet; - - if (!m_sink->open(QIODevice::WriteOnly)) - packet << FilePushError; - else - packet << FilePushOpened; - - m_stream->write(packet); -} - -void FilePushExecutor::writeToSink(const QByteArray &data) -{ - auto written = m_sink->write(data); - - StreamPacket packet; - - if (written != data.size()) - packet << FilePushError; - else - packet << FilePushWritten; - - m_stream->write(packet); -} - -void FilePushExecutor::closeSink() -{ - qDebug() << "Closing sink file" << m_sink->fileName(); - m_sink->close(); -} diff --git a/qdbd/filepushexecutor.h b/qdbd/filepushexecutor.h deleted file mode 100644 index 29f11b2..0000000 --- a/qdbd/filepushexecutor.h +++ /dev/null @@ -1,51 +0,0 @@ -/****************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the Qt Debug Bridge. -** -** $QT_BEGIN_LICENSE:COMM$ -** -** 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 http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** $QT_END_LICENSE$ -** -******************************************************************************/ -#ifndef FILEPUSHEXECUTOR_H -#define FILEPUSHEXECUTOR_H - -#include "executor.h" -class Stream; - -QT_BEGIN_NAMESPACE -class QByteArray; -class QFile; -QT_END_NAMESPACE - -#include <memory> - -class FilePushExecutor : public Executor -{ -public: - explicit FilePushExecutor(Stream *stream); - -public slots: - void receive(StreamPacket packet) override; - -private: - void openSink(const QString &path); - void writeToSink(const QByteArray &data); - void closeSink(); - - Stream* m_stream; - std::unique_ptr<QFile> m_sink; -}; - -#endif // FILEPUSHEXECUTOR_H diff --git a/qdbd/handshakeexecutor.cpp b/qdbd/handshakeexecutor.cpp index b5dc9cb..f40ff97 100644 --- a/qdbd/handshakeexecutor.cpp +++ b/qdbd/handshakeexecutor.cpp @@ -20,7 +20,7 @@ ******************************************************************************/ #include "handshakeexecutor.h" -#include "stream.h" +#include "libqdb/stream.h" #include <QtCore/qdebug.h> #include <QtCore/qfile.h> diff --git a/qdbd/main.cpp b/qdbd/main.cpp index 208e8c9..17397ac 100644 --- a/qdbd/main.cpp +++ b/qdbd/main.cpp @@ -18,9 +18,9 @@ ** $QT_END_LICENSE$ ** ******************************************************************************/ +#include "libqdb/protocol/qdbtransport.h" #include "usb-gadget/usbgadget.h" #include "server.h" -#include "protocol/qdbtransport.h" #include <QtCore/qcommandlineparser.h> #include <QtCore/qcoreapplication.h> diff --git a/qdbd/processexecutor.cpp b/qdbd/processexecutor.cpp deleted file mode 100644 index 7ea2e6c..0000000 --- a/qdbd/processexecutor.cpp +++ /dev/null @@ -1,150 +0,0 @@ -/****************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the Qt Debug Bridge. -** -** $QT_BEGIN_LICENSE:COMM$ -** -** 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 http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** $QT_END_LICENSE$ -** -******************************************************************************/ -#include "processexecutor.h" - -#include "../utils/make_unique.h" -#include "processcommon.h" -#include "stream.h" - -#include <QtCore/qdatastream.h> -#include <QtCore/qdebug.h> -#include <QtCore/qprocess.h> - -ProcessExecutor::ProcessExecutor(Stream *stream) - : m_stream{stream}, - m_process{nullptr} -{ - if (m_stream) { - connect(m_stream, &Stream::packetAvailable, this, &Executor::receive); - connect(m_stream, &Stream::closed, this, &Executor::onStreamClosed); - } -} - -void ProcessExecutor::receive(StreamPacket packet) -{ - uint32_t typeValue; - packet >> typeValue; - auto type = toProcessPacketType(typeValue); - switch (type) { - case ProcessStart: { - QString command; - QStringList arguments; - packet >> command >> arguments; - startProcess(command, arguments); - break; - } - case ProcessWrite: { - QByteArray data; - packet >> data; - writeToProcess(data); - break; - } - default: - Q_ASSERT_X(false, "ProcessExecutor::receive", "Unsupported ProcessPacketType"); - break; - } -} - -void ProcessExecutor::onStarted() -{ - qDebug() << "Process started"; - - StreamPacket packet; - packet << ProcessStarted; - - if (m_stream) - m_stream->write(packet); -} - -void ProcessExecutor::onReadyRead() -{ - qDebug() << "Process readyRead"; - auto size = m_process->bytesAvailable(); - QByteArray read = m_process->read(size); - - StreamPacket packet; - packet << ProcessRead; - packet << read; - - if (m_stream) - m_stream->write(packet); -} - -void ProcessExecutor::onFinished(int exitCode, QProcess::ExitStatus exitStatus) -{ - qDebug() << "Process finished:" << exitCode; - - QByteArray output = m_process->readAll(); - - StreamPacket packet; - packet << ProcessFinished; - packet << exitCode; - packet << (exitStatus == QProcess::NormalExit); - packet << output; - - if (m_stream) - m_stream->write(packet); -} - -void ProcessExecutor::onErrorOccurred(QProcess::ProcessError error) -{ - qDebug() << "Process error:" << error; - - StreamPacket packet; - packet << ProcessError; - uint32_t errorValue = static_cast<uint32_t>(error); - packet << errorValue; - - if (m_stream) - m_stream->write(packet); -} - -void ProcessExecutor::onStreamClosed() -{ - m_stream = nullptr; - if (m_process) { - m_process->kill(); - } -} - -void ProcessExecutor::startProcess(const QString &command, const QStringList &arguments) -{ - m_process = make_unique<QProcess>(); - // merge stdout and stderr - m_process->setProcessChannelMode(QProcess::MergedChannels); - - connect(m_process.get(), &QProcess::started, this, &ProcessExecutor::onStarted); - connect(m_process.get(), &QProcess::readyRead, this, &ProcessExecutor::onReadyRead); - connect(m_process.get(), static_cast<void (QProcess::*)(int, QProcess::ExitStatus)>(&QProcess::finished), - this, &ProcessExecutor::onFinished); - connect(m_process.get(), &QProcess::errorOccurred, this, &ProcessExecutor::onErrorOccurred); - - qDebug() << "Running" << command << arguments; - m_process->start(command, arguments); -} - -void ProcessExecutor::writeToProcess(const QByteArray &data) -{ - Q_ASSERT(m_process); - - qDebug() << "Writing to process:" << data; - m_process->write(data); -} diff --git a/qdbd/processexecutor.h b/qdbd/processexecutor.h deleted file mode 100644 index 2856391..0000000 --- a/qdbd/processexecutor.h +++ /dev/null @@ -1,59 +0,0 @@ -/****************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the Qt Debug Bridge. -** -** $QT_BEGIN_LICENSE:COMM$ -** -** 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 http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** $QT_END_LICENSE$ -** -******************************************************************************/ -#ifndef PROCESSEXECUTOR_H -#define PROCESSEXECUTOR_H - -#include "executor.h" -class Stream; - -#include "QtCore/qprocess.h" -QT_BEGIN_NAMESPACE -class QByteArray; -class QDataStream; -QT_END_NAMESPACE - -#include <memory> - -class ProcessExecutor : public Executor -{ - Q_OBJECT -public: - explicit ProcessExecutor(Stream *stream); - -public slots: - void receive(StreamPacket packet) override; - -private slots: - void onStarted(); - void onReadyRead(); - void onFinished(int exitCode, QProcess::ExitStatus exitStatus); - void onErrorOccurred(QProcess::ProcessError error); - void onStreamClosed(); - -private: - void startProcess(const QString &command, const QStringList &arguments); - void writeToProcess(const QByteArray &data); - - Stream *m_stream; - std::unique_ptr<QProcess> m_process; -}; - -#endif // PROCESSEXECUTOR_H diff --git a/qdbd/qdbd.pro b/qdbd/qdbd.pro index 76ec5df..929d753 100644 --- a/qdbd/qdbd.pro +++ b/qdbd/qdbd.pro @@ -13,31 +13,24 @@ SOURCES += \ createexecutor.cpp \ echoexecutor.cpp \ executor.cpp \ - filepullexecutor.cpp \ - filepushexecutor.cpp \ handshakeexecutor.cpp \ main.cpp \ - processexecutor.cpp \ server.cpp \ usb-gadget/usbgadget.cpp \ usb-gadget/usbgadgetreader.cpp \ usb-gadget/usbgadgetwriter.cpp \ - HEADERS += \ createexecutor.h \ echoexecutor.h \ executor.h \ - filepullexecutor.h \ - filepushexecutor.h \ handshakeexecutor.h \ - processexecutor.h \ server.h \ usb-gadget/usbgadget.h \ usb-gadget/usbgadgetreader.h \ usb-gadget/usbgadgetwriter.h \ -INCLUDEPATH += $$PWD/../libqdb +INCLUDEPATH += $$PWD/../ LIBS = -L$$OUT_PWD/../libqdb -lqdb QMAKE_RPATHDIR += ../libqdb diff --git a/qdbd/server.cpp b/qdbd/server.cpp index 16b0476..2757c70 100644 --- a/qdbd/server.cpp +++ b/qdbd/server.cpp @@ -20,13 +20,13 @@ ******************************************************************************/ #include "server.h" -#include "../utils/make_unique.h" #include "createexecutor.h" #include "echoexecutor.h" -#include "protocol/protocol.h" -#include "protocol/qdbmessage.h" -#include "protocol/qdbtransport.h" -#include "stream.h" +#include "libqdb/make_unique.h" +#include "libqdb/protocol/protocol.h" +#include "libqdb/protocol/qdbmessage.h" +#include "libqdb/protocol/qdbtransport.h" +#include "libqdb/stream.h" #include <QtCore/qdebug.h> #include <QtCore/qloggingcategory.h> diff --git a/qdbd/server.h b/qdbd/server.h index 6f5d36a..8f8bf09 100644 --- a/qdbd/server.h +++ b/qdbd/server.h @@ -21,7 +21,7 @@ #ifndef SERVER_H #define SERVER_H -#include "abstractconnection.h" +#include "libqdb/abstractconnection.h" class Executor; class QdbMessage; class QdbTransport; diff --git a/qdbd/usb-gadget/usbgadget.cpp b/qdbd/usb-gadget/usbgadget.cpp index 6d65312..d660b22 100644 --- a/qdbd/usb-gadget/usbgadget.cpp +++ b/qdbd/usb-gadget/usbgadget.cpp @@ -20,9 +20,8 @@ ******************************************************************************/ #include "usbgadget.h" -#include "../utils/make_unique.h" -#include "protocol/protocol.h" -#include "protocol/qdbmessage.h" +#include "libqdb/make_unique.h" +#include "libqdb/qdbconstants.h" #include "usb-gadget/usbgadgetreader.h" #include "usb-gadget/usbgadgetwriter.h" diff --git a/qdbd/usb-gadget/usbgadgetreader.cpp b/qdbd/usb-gadget/usbgadgetreader.cpp index 2aa6bf0..dfb5600 100644 --- a/qdbd/usb-gadget/usbgadgetreader.cpp +++ b/qdbd/usb-gadget/usbgadgetreader.cpp @@ -20,8 +20,8 @@ ******************************************************************************/ #include "usbgadgetreader.h" -#include "protocol/protocol.h" -#include "protocol/qdbmessage.h" +#include "libqdb/protocol/protocol.h" +#include "libqdb/protocol/qdbmessage.h" #include <QtCore/qdebug.h> #include <QtCore/qfile.h> diff --git a/qdbd/usb-gadget/usbgadgetwriter.cpp b/qdbd/usb-gadget/usbgadgetwriter.cpp index 315514a..3e48349 100644 --- a/qdbd/usb-gadget/usbgadgetwriter.cpp +++ b/qdbd/usb-gadget/usbgadgetwriter.cpp @@ -20,8 +20,8 @@ ******************************************************************************/ #include "usbgadgetwriter.h" -#include "protocol/protocol.h" -#include "protocol/qdbmessage.h" +#include "libqdb/protocol/protocol.h" +#include "libqdb/protocol/qdbmessage.h" #include <QtCore/qdebug.h> #include <QtCore/qfile.h> diff --git a/tests/servicetest.cpp b/tests/servicetest.cpp index 099a49f..da38de9 100644 --- a/tests/servicetest.cpp +++ b/tests/servicetest.cpp @@ -18,16 +18,13 @@ ** $QT_END_LICENSE$ ** ******************************************************************************/ -#include "../client/connection.h" -#include "../client/filepullservice.h" -#include "../client/filepushservice.h" -#include "../client/processservice.h" -#include "../client/echoservice.h" -#include "../utils/make_unique.h" -#include "usb/devicemanagement.h" -#include "usb/usbconnection.h" -#include "protocol/qdbtransport.h" -#include "protocol/services.h" +#include "libqdb/make_unique.h" +#include "libqdb/protocol/qdbtransport.h" +#include "libqdb/protocol/services.h" +#include "libqdb/usb/devicemanagement.h" +#include "libqdb/usb/usbconnection.h" +#include "qdb/server/connection.h" +#include "qdb/server/echoservice.h" #include <QtCore/qdebug.h> #include <QtCore/qregularexpression.h> @@ -53,32 +50,9 @@ class ServiceTest : public QObject { Q_OBJECT private slots: - void initTestCase(); void echo(); - void processOutput(); - void processMultipleOutput(); - void processErrorCode(); - void processNonExistent(); - void processCrash(); - void processInput(); - void processMultipleInput(); - void filePush(); - void filePushNonexistent(); - void filePull(); - void filePullNonexistent(); - void filePullToUnopenable(); }; -const QString pushPullFileName = "qdbtestfile1"; -static QByteArray pushPullFileContents = "abcd\nefgh\n"; -const QString nonexistentFileName{"qdbtestfile2"}; - -void ServiceTest::initTestCase() -{ - qRegisterMetaType<QProcess::ProcessError>("QProcess::ProcessError"); - qRegisterMetaType<QProcess::ExitStatus>("QProcess::ExitStatus"); -} - void ServiceTest::echo() { ConnectionContext ctx; @@ -96,414 +70,5 @@ void ServiceTest::echo() QCOMPARE(spy[0][0].toByteArray(), QByteArray{"ABCD"}); } -void ServiceTest::processOutput() -{ - ConnectionContext ctx; - - QByteArray output; - - ProcessService processService{&ctx.connection}; - connect(&processService, &ProcessService::executionError, [](QProcess::ProcessError error) { - qDebug() << "Command not run, error:" << error; - QFAIL("Command was not run successfully"); - }); - connect(&processService, &Service::initialized, [&]() { - processService.execute("echo", {"ABCD"}); - }); - connect(&processService, &ProcessService::readyRead, [&]() { - output.append(processService.read()); - }); - QSignalSpy spy{&processService, &ProcessService::executed}; - - processService.initialize(); - - spy.wait(testTimeout); - QCOMPARE(spy.count(), 1); - auto exitCode = spy[0][0].toInt(); - QProcess::ExitStatus exitStatus = spy[0][1].value<QProcess::ExitStatus>(); - auto finalOutput = spy[0][2].toByteArray(); - output.append(finalOutput); - QCOMPARE(exitCode, 0); - QCOMPARE(exitStatus, QProcess::NormalExit); - QCOMPARE(output, QByteArray{"ABCD\n"}); -} - -void ServiceTest::processMultipleOutput() -{ - ConnectionContext ctx; - - QByteArray output; - - ProcessService processService{&ctx.connection}; - connect(&processService, &ProcessService::executionError, [](QProcess::ProcessError error) { - qDebug() << "Command not run, error:" << error; - QFAIL("Command was not run successfully"); - }); - - connect(&processService, &Service::initialized, [&]() { - processService.execute("sh", {"-c", "echo abcd && sleep 1 && echo defg"}); - }); - connect(&processService, &ProcessService::readyRead, [&]() { - output.append(processService.read()); - }); - QSignalSpy readyReadSpy{&processService, &ProcessService::readyRead}; - QSignalSpy executedSpy{&processService, &ProcessService::executed}; - - processService.initialize(); - - executedSpy.wait(1000 + testTimeout); - QCOMPARE(executedSpy.count(), 1); - // In principle there could be only one (or more than two) readyRead, but in - // practice the above command seems split into two outputs and otherwise - // this test is not fulfilling its purpose. - QCOMPARE(readyReadSpy.count(), 2); - auto exitCode = executedSpy[0][0].toInt(); - QProcess::ExitStatus exitStatus = executedSpy[0][1].value<QProcess::ExitStatus>(); - auto finalOutput = executedSpy[0][2].toByteArray(); - output.append(finalOutput); - QCOMPARE(exitCode, 0); - QCOMPARE(exitStatus, QProcess::NormalExit); - QCOMPARE(output, QByteArray{"abcd\ndefg\n"}); -} - -void ServiceTest::processErrorCode() -{ - ConnectionContext ctx; - - ProcessService processService{&ctx.connection}; - connect(&processService, &ProcessService::executionError, [](QProcess::ProcessError error) { - qDebug() << "Command not run, error:" << error; - QFAIL("Command was not run successfully"); - }); - connect(&processService, &Service::initialized, [&]() { - processService.execute("test", {"-z", "ABCD"}); - }); - QSignalSpy spy{&processService, &ProcessService::executed}; - - processService.initialize(); - - spy.wait(testTimeout); - QCOMPARE(spy.count(), 1); - auto exitCode = spy[0][0].toInt(); - QProcess::ExitStatus exitStatus = spy[0][1].value<QProcess::ExitStatus>(); - auto output = spy[0][2].toString(); - QCOMPARE(exitCode, 1); - QCOMPARE(exitStatus, QProcess::NormalExit); - QCOMPARE(output, QString{""}); -} - -void ServiceTest::processNonExistent() -{ - ConnectionContext ctx; - - ProcessService processService{&ctx.connection}; - connect(&processService, &ProcessService::executed, [](int, QProcess::ExitStatus, QString) { - QFAIL("Command was unexpectedly run successfully"); - }); - connect(&processService, &Service::initialized, [&]() { - processService.execute("lsfdajlvaie", {}); - }); - QSignalSpy spy{&processService, &ProcessService::executionError}; - - processService.initialize(); - - spy.wait(testTimeout); - QCOMPARE(spy.count(), 1); - auto error = spy[0][0].value<QProcess::ProcessError>(); - QCOMPARE(error, QProcess::FailedToStart); -} - -void ServiceTest::processCrash() -{ - ConnectionContext ctx; - - ProcessService processService{&ctx.connection}; - connect(&processService, &Service::initialized, [&]() { - // Crash the process by having it send SIGSEGV to itself - processService.execute("sh", {"-c", "kill -SEGV $$"}); - }); - QSignalSpy errorSpy{&processService, &ProcessService::executionError}; - QSignalSpy executedSpy{&processService, &ProcessService::executed}; - - processService.initialize(); - - errorSpy.wait(testTimeout); - QCOMPARE(errorSpy.count(), 1); - auto error = errorSpy[0][0].value<QProcess::ProcessError>(); - QCOMPARE(error, QProcess::Crashed); - - executedSpy.wait(testTimeout); - QCOMPARE(executedSpy.count(), 1); - auto exitCode = executedSpy[0][0].toInt(); - auto exitStatus = executedSpy[0][1].value<QProcess::ExitStatus>(); - auto output = executedSpy[0][2].toString(); - QCOMPARE(exitCode, 11); // 11 for segfault - QCOMPARE(exitStatus, QProcess::CrashExit); - QCOMPARE(output, QString{""}); -} - -void ServiceTest::processInput() -{ - ConnectionContext ctx; - - QByteArray output; - - ProcessService processService{&ctx.connection}; - connect(&processService, &ProcessService::executionError, [](QProcess::ProcessError error) { - qDebug() << "Command not run, error:" << error; - QFAIL("Command was not run successfully"); - }); - connect(&processService, &Service::initialized, [&]() { - processService.execute("sh", {"-c", "read input; echo $input"}); - }); - connect(&processService, &ProcessService::readyRead, [&]() { - output.append(processService.read()); - }); - connect(&processService, &ProcessService::started, [&]() { - processService.write("abcd\n"); - }); - QSignalSpy spy{&processService, &ProcessService::executed}; - - processService.initialize(); - - spy.wait(testTimeout); - QCOMPARE(spy.count(), 1); - auto exitCode = spy[0][0].toInt(); - QProcess::ExitStatus exitStatus = spy[0][1].value<QProcess::ExitStatus>(); - auto finalOutput = spy[0][2].toByteArray(); - output.append(finalOutput); - QCOMPARE(exitCode, 0); - QCOMPARE(exitStatus, QProcess::NormalExit); - QCOMPARE(output, QByteArray{"abcd\n"}); -} - -void ServiceTest::processMultipleInput() -{ - ConnectionContext ctx; - - QByteArray output; - - ProcessService processService{&ctx.connection}; - connect(&processService, &ProcessService::executionError, [](QProcess::ProcessError error) { - qDebug() << "Command not run, error:" << error; - QFAIL("Command was not run successfully"); - }); - connect(&processService, &Service::initialized, [&]() { - processService.execute("sh", {"-c", "for i in {1..2}; do read input; echo $input; done"}); - }); - connect(&processService, &ProcessService::readyRead, [&]() { - output.append(processService.read()); - }); - connect(&processService, &ProcessService::started, [&]() { - processService.write("abcd\n"); - processService.write("efgh\n"); - }); - QSignalSpy spy{&processService, &ProcessService::executed}; - - processService.initialize(); - - spy.wait(testTimeout); - QCOMPARE(spy.count(), 1); - auto exitCode = spy[0][0].toInt(); - QProcess::ExitStatus exitStatus = spy[0][1].value<QProcess::ExitStatus>(); - auto finalOutput = spy[0][2].toByteArray(); - output.append(finalOutput); - QCOMPARE(exitCode, 0); - QCOMPARE(exitStatus, QProcess::NormalExit); - QCOMPARE(output, QByteArray{"abcd\nefgh\n"}); -} - -void ServiceTest::filePush() -{ - ConnectionContext ctx; - - // Write source file - QFile source{pushPullFileName}; - QVERIFY(source.open(QIODevice::WriteOnly)); - source.write(pushPullFileContents); - source.close(); - - // Push source file to device (it's cleaned up in filePullToUnopenable()) - FilePushService filePushService{&ctx.connection}; - connect(&filePushService, &FilePushService::error, [](QString error) { - qCritical() << error; - QFAIL("Error while pushing file."); - }); - connect(&filePushService, &Service::initialized, [&]() { - filePushService.push(pushPullFileName, pushPullFileName); - }); - QSignalSpy pushSpy{&filePushService, &FilePushService::pushed}; - - filePushService.initialize(); - - pushSpy.wait(testTimeout); - QCOMPARE(pushSpy.count(), 1); - - // Remove source file - source.remove(); - - // Check contents on device - QByteArray output; - - ProcessService processService{&ctx.connection}; - connect(&processService, &ProcessService::executionError, [](QProcess::ProcessError error) { - qDebug() << "Command not run, error:" << error; - QFAIL("Command was not run successfully"); - }); - connect(&processService, &Service::initialized, [&]() { - processService.execute("cat", {pushPullFileName}); - }); - connect(&processService, &ProcessService::readyRead, [&]() { - output.append(processService.read()); - }); - QSignalSpy processSpy{&processService, &ProcessService::executed}; - - processService.initialize(); - - processSpy.wait(testTimeout); - QCOMPARE(processSpy.count(), 1); - auto exitCode = processSpy[0][0].toInt(); - QProcess::ExitStatus exitStatus = processSpy[0][1].value<QProcess::ExitStatus>(); - auto finalOutput = processSpy[0][2].toByteArray(); - output.append(finalOutput); - QCOMPARE(exitCode, 0); - QCOMPARE(exitStatus, QProcess::NormalExit); - QCOMPARE(output, pushPullFileContents); -} - -void ServiceTest::filePushNonexistent() -{ - QVERIFY(!QFile::exists(nonexistentFileName)); - - ConnectionContext ctx; - - FilePushService filePushService{&ctx.connection}; - connect(&filePushService, &FilePushService::pushed, []() { - QFAIL("Unexpectedly succeeded pushing nonexistent file."); - }); - connect(&filePushService, &Service::initialized, [&]() { - filePushService.push(nonexistentFileName, nonexistentFileName); - }); - QSignalSpy spy{&filePushService, &FilePushService::error}; - - filePushService.initialize(); - - spy.wait(testTimeout); - QCOMPARE(spy.count(), 1); - QRegularExpression regexp{"^Could not open.+host$"}; - auto errorMessage = spy[0][0].toString(); - QVERIFY(regexp.match(errorMessage).hasMatch()); -} - -// This test relies on the file pushed in filePush() -void ServiceTest::filePull() -{ - ConnectionContext ctx; - - // Pull source file from device - FilePullService filePullService{&ctx.connection}; - connect(&filePullService, &FilePullService::error, [](QString error) { - qCritical() << error; - QFAIL("Error while pulling file"); - }); - connect(&filePullService, &Service::initialized, [&]() { - filePullService.pull(pushPullFileName, pushPullFileName); - }); - QSignalSpy pullSpy{&filePullService, &FilePullService::pulled}; - - filePullService.initialize(); - - pullSpy.wait(testTimeout); - QCOMPARE(pullSpy.count(), 1); - - // Check contents - QFile sink{pushPullFileName}; - QVERIFY(sink.open(QIODevice::ReadOnly)); - auto contents = sink.readAll(); - QCOMPARE(contents, pushPullFileContents); - - sink.close(); - sink.remove(); -} - -void ServiceTest::filePullNonexistent() -{ - const QString nonexistentFileName{"qdbtestfile2"}; - - ConnectionContext ctx; - - // Pull source file from device - FilePullService filePullService{&ctx.connection}; - connect(&filePullService, &FilePullService::pulled, []() { - QFAIL("Unexpectedly succeeded pulling nonexistent file"); - }); - connect(&filePullService, &Service::initialized, [&]() { - filePullService.pull(nonexistentFileName, nonexistentFileName); - }); - QSignalSpy spy{&filePullService, &FilePullService::error}; - - filePullService.initialize(); - - spy.wait(testTimeout); - QCOMPARE(spy.count(), 1); - QRegularExpression regexp{"^Could not open.+device$"}; - auto errorMessage = spy[0][0].toString(); - QVERIFY(regexp.match(errorMessage).hasMatch()); -} - -// This test relies on the file pushed in filePush() and removes it in the end -void ServiceTest::filePullToUnopenable() -{ - const QString fileName{"qdbtestfile2"}; - - QFile blocker{fileName}; - blocker.open(QIODevice::WriteOnly); - blocker.setPermissions(QFileDevice::ReadUser); - blocker.close(); - - ConnectionContext ctx; - - // Pull source file from device - FilePullService filePullService{&ctx.connection}; - connect(&filePullService, &FilePullService::pulled, []() { - QFAIL("Unexpectedly succeeded pulling into file that can't be written to"); - }); - connect(&filePullService, &Service::initialized, [&]() { - filePullService.pull(pushPullFileName, fileName); - }); - QSignalSpy spy{&filePullService, &FilePullService::error}; - - filePullService.initialize(); - - spy.wait(testTimeout); - - blocker.remove(); - - QCOMPARE(spy.count(), 1); - QRegularExpression regexp{"^Could not open.+host$"}; - auto errorMessage = spy[0][0].toString(); - QVERIFY(regexp.match(errorMessage).hasMatch()); - - // Remove file from device - ProcessService processService{&ctx.connection}; - connect(&processService, &ProcessService::executionError, [](QProcess::ProcessError error) { - qDebug() << "Command not run, error:" << error; - QFAIL("Command was not run successfully"); - }); - connect(&processService, &Service::initialized, [&]() { - processService.execute("rm", {pushPullFileName}); - }); - QSignalSpy processSpy{&processService, &ProcessService::executed}; - - processService.initialize(); - - processSpy.wait(testTimeout); - QCOMPARE(processSpy.count(), 1); - auto exitCode = processSpy[0][0].toInt(); - QProcess::ExitStatus exitStatus = processSpy[0][1].value<QProcess::ExitStatus>(); - QCOMPARE(exitCode, 0); - QCOMPARE(exitStatus, QProcess::NormalExit); -} - QTEST_GUILESS_MAIN(ServiceTest) #include "servicetest.moc" diff --git a/tests/servicetest.pro b/tests/servicetest.pro index a5914f8..b0ca1cf 100644 --- a/tests/servicetest.pro +++ b/tests/servicetest.pro @@ -7,23 +7,17 @@ CONFIG -= app_bundle TEMPLATE = app HEADERS += \ - ../client/connection.h \ - ../client/filepullservice.h \ - ../client/filepushservice.h \ - ../client/processservice.h \ - ../client/echoservice.h \ - ../client/service.h + ../qdb/server/connection.h \ + ../qdb/server/echoservice.h \ + ../qdb/server/service.h SOURCES += \ servicetest.cpp \ - ../client/connection.cpp \ - ../client/filepullservice.cpp \ - ../client/filepushservice.cpp \ - ../client/processservice.cpp \ - ../client/echoservice.cpp \ - ../client/service.cpp + ../qdb/server/connection.cpp \ + ../qdb/server/echoservice.cpp \ + ../qdb/server/service.cpp -INCLUDEPATH += $$PWD/../libqdb +INCLUDEPATH += $$PWD/../ unix { LIBS = -L$$OUT_PWD/../libqdb -lqdb @@ -31,25 +25,25 @@ unix { } win32 { -HEADERS += \ - ../libqdb/protocol/protocol.h \ - ../libqdb/protocol/qdbmessage.h \ - ../libqdb/protocol/qdbtransport.h \ - ../libqdb/stream.h \ - ../libqdb/abstractconnection.h \ - ../libqdb/streampacket.h - -SOURCES += \ - ../libqdb/protocol/qdbmessage.cpp \ - ../libqdb/protocol/qdbtransport.cpp \ - ../libqdb/stream.cpp \ - ../libqdb/abstractconnection.cpp \ - ../libqdb/streampacket.cpp - -CONFIG(debug, debug|release) { - LIBQDBDIR = $$OUT_PWD/../libqdb/debug -} else { - LIBQDBDIR = $$OUT_PWD/../libqdb/release -} -LIBS = -L$$LIBQDBDIR -lqdb + HEADERS += \ + ../libqdb/protocol/protocol.h \ + ../libqdb/protocol/qdbmessage.h \ + ../libqdb/protocol/qdbtransport.h \ + ../libqdb/stream.h \ + ../libqdb/abstractconnection.h \ + ../libqdb/streampacket.h + + SOURCES += \ + ../libqdb/protocol/qdbmessage.cpp \ + ../libqdb/protocol/qdbtransport.cpp \ + ../libqdb/stream.cpp \ + ../libqdb/abstractconnection.cpp \ + ../libqdb/streampacket.cpp + + CONFIG(debug, debug|release) { + LIBQDBDIR = $$OUT_PWD/../libqdb/debug + } else { + LIBQDBDIR = $$OUT_PWD/../libqdb/release + } + LIBS = -L$$LIBQDBDIR -lqdb } diff --git a/tests/streamtest.cpp b/tests/streamtest.cpp index 0d33d10..c44c585 100644 --- a/tests/streamtest.cpp +++ b/tests/streamtest.cpp @@ -18,13 +18,13 @@ ** $QT_END_LICENSE$ ** ******************************************************************************/ -#include "../utils/make_unique.h" -#include "usb/devicemanagement.h" -#include "usb/usbconnection.h" -#include "protocol/protocol.h" -#include "protocol/qdbmessage.h" -#include "protocol/qdbtransport.h" -#include "protocol/services.h" +#include "libqdb/make_unique.h" +#include "libqdb/protocol/protocol.h" +#include "libqdb/protocol/qdbmessage.h" +#include "libqdb/protocol/qdbtransport.h" +#include "libqdb/protocol/services.h" +#include "libqdb/usb/devicemanagement.h" +#include "libqdb/usb/usbconnection.h" #include <QtCore/qdebug.h> #include <QtCore/qtimer.h> diff --git a/tests/streamtest.pro b/tests/streamtest.pro index 6ff8223..ed45253 100644 --- a/tests/streamtest.pro +++ b/tests/streamtest.pro @@ -8,27 +8,26 @@ TEMPLATE = app SOURCES += streamtest.cpp -INCLUDEPATH += $$PWD/../libqdb +INCLUDEPATH += $$PWD/../ unix { -LIBS = -L$$OUT_PWD/../libqdb -lqdb -QMAKE_RPATHDIR += ../libqdb + LIBS = -L$$OUT_PWD/../libqdb -lqdb + QMAKE_RPATHDIR += ../libqdb } win32 { -HEADERS += \ - ../libqdb/protocol/qdbmessage.h \ - ../libqdb/protocol/qdbtransport.h - -SOURCES += \ - ../libqdb/protocol/qdbmessage.cpp \ - ../libqdb/protocol/qdbtransport.cpp - -CONFIG(debug, debug|release) { - LIBQDBDIR = $$OUT_PWD/../libqdb/debug -} else { - LIBQDBDIR = $$OUT_PWD/../libqdb/release + HEADERS += \ + ../libqdb/protocol/qdbmessage.h \ + ../libqdb/protocol/qdbtransport.h + + SOURCES += \ + ../libqdb/protocol/qdbmessage.cpp \ + ../libqdb/protocol/qdbtransport.cpp + + CONFIG(debug, debug|release) { + LIBQDBDIR = $$OUT_PWD/../libqdb/debug + } else { + LIBQDBDIR = $$OUT_PWD/../libqdb/release + } + LIBS = -L$$LIBQDBDIR -lqdb } -LIBS = -L$$LIBQDBDIR -lqdb -} - diff --git a/tests/tst_stream.cpp b/tests/tst_stream.cpp index 8bdace1..ab4e4d7 100644 --- a/tests/tst_stream.cpp +++ b/tests/tst_stream.cpp @@ -20,8 +20,8 @@ ******************************************************************************/ #include <QtTest/QtTest> -#include "abstractconnection.h" -#include "stream.h" +#include "libqdb/abstractconnection.h" +#include "libqdb/stream.h" class ConnectionStub : public AbstractConnection { diff --git a/tests/tst_stream.pro b/tests/tst_stream.pro index fb690f5..8cde9f5 100644 --- a/tests/tst_stream.pro +++ b/tests/tst_stream.pro @@ -12,33 +12,34 @@ TEMPLATE = app SOURCES += \ tst_stream.cpp \ -INCLUDEPATH += $$PWD/../libqdb +INCLUDEPATH += $$PWD/../ unix { -LIBS = -L$$OUT_PWD/../libqdb -lqdb -QMAKE_RPATHDIR += ../libqdb + LIBS = -L$$OUT_PWD/../libqdb -lqdb + QMAKE_RPATHDIR += ../libqdb } win32 { -HEADERS += \ - ../libqdb/protocol/qdbmessage.h \ - ../libqdb/protocol/qdbtransport.h \ - ../libqdb/stream.h \ - ../libqdb/abstractconnection.h \ - ../libqdb/streampacket.h - -SOURCES += \ - ../libqdb/protocol/qdbmessage.cpp \ - ../libqdb/protocol/qdbtransport.cpp \ - ../libqdb/stream.cpp \ - ../libqdb/abstractconnection.cpp \ - ../libqdb/streampacket.cpp - -CONFIG(debug, debug|release) { - LIBQDBDIR = $$OUT_PWD/../libqdb/debug -} else { - LIBQDBDIR = $$OUT_PWD/../libqdb/release -} -LIBS = -L$$LIBQDBDIR -lqdb + HEADERS += \ + ../libqdb/protocol/qdbmessage.h \ + ../libqdb/protocol/qdbtransport.h \ + ../libqdb/stream.h \ + ../libqdb/abstractconnection.h \ + ../libqdb/streampacket.h + + SOURCES += \ + ../libqdb/protocol/qdbmessage.cpp \ + ../libqdb/protocol/qdbtransport.cpp \ + ../libqdb/stream.cpp \ + ../libqdb/abstractconnection.cpp \ + ../libqdb/streampacket.cpp + + CONFIG(debug, debug|release) { + LIBQDBDIR = $$OUT_PWD/../libqdb/debug + } else { + LIBQDBDIR = $$OUT_PWD/../libqdb/release + } + + LIBS = -L$$LIBQDBDIR -lqdb } |