diff options
author | Lars Knoll <lars.knoll@nokia.com> | 2012-08-06 15:48:28 +0200 |
---|---|---|
committer | Qt by Nokia <qt-info@nokia.com> | 2012-08-20 11:07:18 +0200 |
commit | c14a9b92de20b8b114ab26a7d91cf3572bfbdc70 (patch) | |
tree | a6ec2b35602633b380b9e1ea5433ba8e628b5da2 /src/runonphone | |
parent | 5a8fe661806cfb3a63247f8adf7e38036a5a73fe (diff) | |
download | qttools-c14a9b92de20b8b114ab26a7d91cf3572bfbdc70.tar.gz |
Remove runonphone
runonphone was a pure symbian utility. Remove it.
Change-Id: I6fa1b7884fb86a161ff4f7f8ba7f54de687faa43
Reviewed-by: Friedemann Kleint <Friedemann.Kleint@nokia.com>
Reviewed-by: Jason Barron <jason.barron@nokia.com>
Diffstat (limited to 'src/runonphone')
35 files changed, 0 insertions, 9538 deletions
diff --git a/src/runonphone/main.cpp b/src/runonphone/main.cpp deleted file mode 100644 index ad15ad92f..000000000 --- a/src/runonphone/main.cpp +++ /dev/null @@ -1,277 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the tools applications of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <QCoreApplication> -#include <QTextStream> -#include <QStringList> -#include <QScopedPointer> -#include <QTimer> -#include <QFileInfo> -#include "symbianutils/trkutils.h" -#include "symbianutils/trkdevice.h" -#include "symbianutils/launcher.h" - -#include "trksignalhandler.h" -#include "serenum.h" -#include "ossignalconverter.h" - -void printUsage(QTextStream& outstream, QString exeName) -{ - outstream << exeName << " [options] [program] [program arguments]" << endl - << "-s, --sis <local file> specify sis file to install" << endl - << "-p, --portname <COMx> specify COM port to use by device name" << endl - << "-f, --portfriendlyname <substring> specify COM port to use by friendly name" << endl - << "-t, --timeout <milliseconds> terminate test if timeout occurs" << endl - << "-v, --verbose show debugging output" << endl - << "-q, --quiet hide progress messages" << endl - << "-u, --upload <local file> upload executable file to phone" << endl - << "-d, --download <remote file> <local file> copy file from phone to PC after running test" << endl - << "--nocrashlog Don't capture call stack if test crashes" << endl - << "--crashlogpath <dir> Path to save crash logs (default=working dir)" << endl - << endl - << "USB COM ports can usually be autodetected, use -p or -f to force a specific port." << endl - << "If using System TRK, it is possible to copy the program directly to sys/bin on the phone." << endl - << "-s can be used with both System and Application TRK to install the program" << endl; -} - -#define CHECK_PARAMETER_EXISTS if(!it.hasNext()) { printUsage(outstream, args[0]); return 1; } -int main(int argc, char *argv[]) -{ - QCoreApplication a(argc, argv); - - QString serialPortName; - QString serialPortFriendlyName; - QString sisFile; - QString exeFile; - QStringList cmdLine; - QStringList args = QCoreApplication::arguments(); - QTextStream outstream(stdout); - QTextStream errstream(stderr); - QString uploadLocalFile; - QString downloadRemoteFile; - QString downloadLocalFile; - int loglevel=1; - int timeout=0; - bool crashlog = true; - QString crashlogpath; - QListIterator<QString> it(args); - it.next(); //skip name of program - while (it.hasNext()) { - QString arg = it.next(); - - if (arg.startsWith("-")) { - if (arg == "--portname" || arg == "-p") { - CHECK_PARAMETER_EXISTS - serialPortName = it.next(); - } - else if (arg == "--portfriendlyname" || arg == "-f") { - CHECK_PARAMETER_EXISTS - serialPortFriendlyName = it.next(); - } - else if (arg == "--sis" || arg == "-s") { - CHECK_PARAMETER_EXISTS - sisFile = it.next(); - if (!QFileInfo(sisFile).exists()) { - errstream << "Sis file (" << sisFile << ") doesn't exist" << endl; - return 1; - } - } - else if (arg == "--upload" || arg == "-u") { - CHECK_PARAMETER_EXISTS - uploadLocalFile = it.next(); - if (!QFileInfo(uploadLocalFile).exists()) { - errstream << "Executable file (" << uploadLocalFile << ") doesn't exist" << endl; - return 1; - } - if (!(QFileInfo(uploadLocalFile).suffix() == "exe")) { - errstream << "File (" << uploadLocalFile << ") must be an executable" << endl; - return 1; - } - } - else if (arg == "--download" || arg == "-d") { - CHECK_PARAMETER_EXISTS - downloadRemoteFile = it.next(); - CHECK_PARAMETER_EXISTS - downloadLocalFile = it.next(); - } - else if (arg == "--timeout" || arg == "-t") { - CHECK_PARAMETER_EXISTS - bool ok; - timeout = it.next().toInt(&ok); - if (!ok) { - errstream << "Timeout must be specified in milliseconds" << endl; - return 1; - } - } - else if (arg == "--verbose" || arg == "-v") - loglevel=2; - else if (arg == "--quiet" || arg == "-q") - loglevel=0; - else if (arg == "--nocrashlog") - crashlog = false; - else if (arg == "--crashlogpath") { - CHECK_PARAMETER_EXISTS - crashlogpath = it.next(); - } - else - errstream << "unknown command line option " << arg << endl; - } else { - exeFile = arg; - while(it.hasNext()) { - cmdLine.append(it.next()); - } - } - } - - if (exeFile.isEmpty() && sisFile.isEmpty() && uploadLocalFile.isEmpty() && - (downloadLocalFile.isEmpty() || downloadRemoteFile.isEmpty())) { - printUsage(outstream, args[0]); - return 1; - } - - if (!uploadLocalFile.isEmpty() && (!downloadLocalFile.isEmpty() || !downloadRemoteFile.isEmpty())) { - errstream << "Upload option can't be used together with download" << endl; - printUsage(outstream, args[0]); - return 1; - } - - if (serialPortName.isEmpty()) { - if (loglevel > 0) - outstream << "Detecting serial ports" << endl; - foreach (const SerialPortId &id, enumerateSerialPorts(loglevel)) { - if (loglevel > 0) - outstream << "Port Name: " << id.portName << ", " - << "Friendly Name:" << id.friendlyName << endl; - if (!id.friendlyName.isEmpty() - && serialPortFriendlyName.isEmpty() - && (id.friendlyName.contains("symbian", Qt::CaseInsensitive) - || id.friendlyName.contains("s60", Qt::CaseInsensitive) - || id.friendlyName.contains("nokia", Qt::CaseInsensitive))) { - serialPortName = id.portName; - break; - } else if (!id.friendlyName.isEmpty() - && !serialPortFriendlyName.isEmpty() - && id.friendlyName.contains(serialPortFriendlyName)) { - serialPortName = id.portName; - break; - } - } - if (serialPortName.isEmpty()) { - errstream << "No phone found, ensure USB cable is connected or specify manually with -p" << endl; - return 1; - } - } - - QScopedPointer<trk::Launcher> launcher; - launcher.reset(new trk::Launcher(trk::Launcher::ActionPingOnly)); - QFileInfo exeInfo(exeFile); - QFileInfo uploadInfo(uploadLocalFile); - if (!sisFile.isEmpty()) { - launcher->addStartupActions(trk::Launcher::ActionCopyInstall); - launcher->setCopyFileName(sisFile, "c:\\data\\testtemp.sis"); - launcher->setInstallFileName("c:\\data\\testtemp.sis"); - } - else if (!uploadLocalFile.isEmpty() && uploadInfo.exists()) { - launcher->addStartupActions(trk::Launcher::ActionCopy); - launcher->setCopyFileName(uploadLocalFile, QString("c:\\sys\\bin\\") + uploadInfo.fileName()); - } - if (!exeFile.isEmpty()) { - launcher->addStartupActions(trk::Launcher::ActionRun); - launcher->setFileName(QString("c:\\sys\\bin\\") + exeInfo.fileName()); - launcher->setCommandLineArgs(cmdLine); - } - if (!downloadRemoteFile.isEmpty() && !downloadLocalFile.isEmpty()) { - launcher->addStartupActions(trk::Launcher::ActionDownload); - launcher->setDownloadFileName(downloadRemoteFile, downloadLocalFile); - } - if (loglevel > 0) - outstream << "Connecting to target via " << serialPortName << endl; - launcher->setTrkServerName(serialPortName); - - if (loglevel > 1) - launcher->setVerbose(1); - - TrkSignalHandler handler; - handler.setLogLevel(loglevel); - handler.setCrashLogging(crashlog); - handler.setCrashLogPath(crashlogpath); - - QObject::connect(launcher.data(), SIGNAL(copyingStarted()), &handler, SLOT(copyingStarted())); - QObject::connect(launcher.data(), SIGNAL(canNotConnect(const QString &)), &handler, SLOT(canNotConnect(const QString &))); - QObject::connect(launcher.data(), SIGNAL(canNotCreateFile(const QString &, const QString &)), &handler, SLOT(canNotCreateFile(const QString &, const QString &))); - QObject::connect(launcher.data(), SIGNAL(canNotWriteFile(const QString &, const QString &)), &handler, SLOT(canNotWriteFile(const QString &, const QString &))); - QObject::connect(launcher.data(), SIGNAL(canNotCloseFile(const QString &, const QString &)), &handler, SLOT(canNotCloseFile(const QString &, const QString &))); - QObject::connect(launcher.data(), SIGNAL(installingStarted()), &handler, SLOT(installingStarted())); - QObject::connect(launcher.data(), SIGNAL(canNotInstall(const QString &, const QString &)), &handler, SLOT(canNotInstall(const QString &, const QString &))); - QObject::connect(launcher.data(), SIGNAL(installingFinished()), &handler, SLOT(installingFinished())); - QObject::connect(launcher.data(), SIGNAL(startingApplication()), &handler, SLOT(startingApplication())); - QObject::connect(launcher.data(), SIGNAL(applicationRunning(uint)), &handler, SLOT(applicationRunning(uint))); - QObject::connect(launcher.data(), SIGNAL(canNotRun(const QString &)), &handler, SLOT(canNotRun(const QString &))); - QObject::connect(launcher.data(), SIGNAL(applicationOutputReceived(const QString &)), &handler, SLOT(applicationOutputReceived(const QString &))); - QObject::connect(launcher.data(), SIGNAL(copyProgress(int)), &handler, SLOT(copyProgress(int))); - QObject::connect(launcher.data(), SIGNAL(stateChanged(int)), &handler, SLOT(stateChanged(int))); - QObject::connect(launcher.data(), SIGNAL(processStopped(uint,uint,uint,QString)), &handler, SLOT(stopped(uint,uint,uint,QString))); - QObject::connect(launcher.data(), SIGNAL(libraryLoaded(trk::Library)), &handler, SLOT(libraryLoaded(trk::Library))); - QObject::connect(launcher.data(), SIGNAL(libraryUnloaded(trk::Library)), &handler, SLOT(libraryUnloaded(trk::Library))); - QObject::connect(launcher.data(), SIGNAL(registersAndCallStackReadComplete(const QList<uint> &,const QByteArray &)), &handler, SLOT(registersAndCallStackReadComplete(const QList<uint> &,const QByteArray &))); - QObject::connect(&handler, SIGNAL(resume(uint,uint)), launcher.data(), SLOT(resumeProcess(uint,uint))); - QObject::connect(&handler, SIGNAL(terminate()), launcher.data(), SLOT(terminate())); - QObject::connect(&handler, SIGNAL(getRegistersAndCallStack(uint,uint)), launcher.data(), SLOT(getRegistersAndCallStack(uint,uint))); - QObject::connect(launcher.data(), SIGNAL(finished()), &handler, SLOT(finished())); - - QObject::connect(OsSignalConverter::instance(), SIGNAL(terminate()), launcher.data(), SLOT(terminate()), Qt::QueuedConnection); - - QTimer timer; - timer.setSingleShot(true); - QObject::connect(&timer, SIGNAL(timeout()), &handler, SLOT(timeout())); - if (timeout > 0) { - timer.start(timeout); - } - - QString errorMessage; - if (!launcher->startServer(&errorMessage)) { - errstream << errorMessage << endl; - return 1; - } - - return a.exec(); -} - diff --git a/src/runonphone/ossignalconverter.cpp b/src/runonphone/ossignalconverter.cpp deleted file mode 100644 index 8f0201b86..000000000 --- a/src/runonphone/ossignalconverter.cpp +++ /dev/null @@ -1,121 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the tools applications of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "ossignalconverter_p.h" -#include <signal.h> -#include <QTimer> -#include <stdio.h> - -Q_GLOBAL_STATIC(OsSignalConverter, osSignalConverter); - -OsSignalConverter* OsSignalConverter::instance() -{ - return osSignalConverter(); -} - -OsSignalConverter::OsSignalConverter() -: d(new OsSignalConverterPrivate(this)) -{ -}; - -OsSignalConverter::~OsSignalConverter() -{ -} - -OsSignalConverterPrivate::OsSignalConverterPrivate(OsSignalConverter* owner) -: QObject(owner), q(owner), poller(new QTimer(this)) -{ - trap(); - connect(poller, SIGNAL(timeout()), this, SLOT(poll())); - poller->start(1000); -} - -OsSignalConverterPrivate::~OsSignalConverterPrivate() -{ - untrap(); -} - -void OsSignalConverterPrivate::trap() -{ - signal(SIGINT, handler); - signal(SIGTERM, handler); -#ifdef SIGBREAK - signal(SIGBREAK, handler); -#endif -#ifdef SIGHUP - signal(SIGHUP, handler); -#endif -#ifdef SIGQUIT - signal(SIGQUIT, handler); -#endif -} - -void OsSignalConverterPrivate::untrap() -{ - signal(SIGINT, SIG_DFL); - signal(SIGTERM, SIG_DFL); -#ifdef SIGBREAK - signal(SIGBREAK, SIG_DFL); -#endif -#ifdef SIGHUP - signal(SIGHUP, SIG_DFL); -#endif -#ifdef SIGQUIT - signal(SIGQUIT, SIG_DFL); -#endif -} - -void OsSignalConverterPrivate::handler(int sig) -{ - untrap(); //allow 2nd ctrl-c to really kill us - terminateRequest = sig; -} - -void OsSignalConverterPrivate::poll() -{ - if (terminateRequest) { - fprintf(stderr, "\n*** caught signal %d, terminating ***\n", terminateRequest); - poller->stop(); - emit q->terminate(); - } -} - -sig_atomic_t OsSignalConverterPrivate::terminateRequest; diff --git a/src/runonphone/ossignalconverter.h b/src/runonphone/ossignalconverter.h deleted file mode 100644 index 3dd8c839a..000000000 --- a/src/runonphone/ossignalconverter.h +++ /dev/null @@ -1,63 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the tools applications of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef OSSIGNALCONVERTER_H -#define OSSIGNALCONVERTER_H -#include <QObject> - -class OsSignalConverterPrivate; - -class OsSignalConverter : public QObject -{ - friend class OsSignalConverterPrivate; - Q_OBJECT -public: - static OsSignalConverter* instance(); - OsSignalConverter(); - ~OsSignalConverter(); -signals: - //emitted when this process is asked to quit, e.g. by SIGINT - void terminate(); -private: - OsSignalConverterPrivate *d; -}; - -#endif // OSSIGNALCONVERTER_H diff --git a/src/runonphone/ossignalconverter_p.h b/src/runonphone/ossignalconverter_p.h deleted file mode 100644 index 035cbf9a8..000000000 --- a/src/runonphone/ossignalconverter_p.h +++ /dev/null @@ -1,71 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the tools applications of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef OSSIGNALCONVERTER_P_H -#define OSSIGNALCONVERTER_P_H -#include "ossignalconverter.h" -#include <signal.h> - -class QTimer; -class OsSignalConverterPrivate : public QObject -{ - Q_OBJECT -public: - OsSignalConverterPrivate(OsSignalConverter* owner); - ~OsSignalConverterPrivate(); -private: - - static void trap(); - static void untrap(); - static void handler(int signal); - -private slots: - - void poll(); - -private: - - OsSignalConverter* q; - static sig_atomic_t terminateRequest; - QTimer *poller; -}; - -#endif // OSSIGNALCONVERTER_P_H diff --git a/src/runonphone/runonphone.pro b/src/runonphone/runonphone.pro deleted file mode 100644 index 7ff361ccf..000000000 --- a/src/runonphone/runonphone.pro +++ /dev/null @@ -1,35 +0,0 @@ -TEMPLATE = app - -QT -= gui -CONFIG += console -CONFIG -= app_bundle - -include(symbianutils/symbianutils.pri) - -SOURCES += main.cpp \ - trksignalhandler.cpp \ - ossignalconverter.cpp - -HEADERS += trksignalhandler.h \ - serenum.h \ - ossignalconverter.h \ - ossignalconverter_p.h - -DEFINES += SYMBIANUTILS_INCLUDE_PRI - -windows { - SOURCES += serenum_win.cpp - LIBS += -lsetupapi \ - -luuid \ - -ladvapi32 -} -else:unix:!symbian { - SOURCES += serenum_unix.cpp - LIBS += -lusb -} -else { - SOURCES += serenum_stub.cpp -} - -target.path=$$[QT_INSTALL_BINS] -INSTALLS += target diff --git a/src/runonphone/serenum.h b/src/runonphone/serenum.h deleted file mode 100644 index 7bd798a56..000000000 --- a/src/runonphone/serenum.h +++ /dev/null @@ -1,56 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the tools applications of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef WIN32SERENUM_H -#define WIN32SERENUM_H - -#include <QString> -#include <QList> - -struct SerialPortId -{ - QString portName; - QString friendlyName; -}; - -QList<SerialPortId> enumerateSerialPorts(int loglevel); - -#endif // WIN32SERENUM_H diff --git a/src/runonphone/serenum_stub.cpp b/src/runonphone/serenum_stub.cpp deleted file mode 100644 index 88246002e..000000000 --- a/src/runonphone/serenum_stub.cpp +++ /dev/null @@ -1,53 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the tools applications of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "serenum.h" -#include <QByteArray> -#include <QString> -#include <QDebug> - -QList<SerialPortId> enumerateSerialPorts() -{ - QList<SerialPortId> list; - qWarning() << "enumerateSerialPorts not implemented"; - return list; -} - diff --git a/src/runonphone/serenum_unix.cpp b/src/runonphone/serenum_unix.cpp deleted file mode 100644 index 1a7b9c7dd..000000000 --- a/src/runonphone/serenum_unix.cpp +++ /dev/null @@ -1,224 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the tools applications of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "serenum.h" -#include <QByteArray> -#include <QString> -#include <QDebug> -#include <QFileInfo> -#include <QDir> - -#include <usb.h> - -class InterfaceInfo -{ -public: - InterfaceInfo(const QString &mf, const QString &pr, int mfid, int prid); - QString manufacturer; - QString product; - int manufacturerid; - int productid; -}; - -InterfaceInfo::InterfaceInfo(const QString &mf, const QString &pr, int mfid, int prid) : - manufacturer(mf), - product(pr), - manufacturerid(mfid), - productid(prid) -{ - if(mf.isEmpty()) - manufacturer = QString("[%1]").arg(mfid, 4, 16, QChar('0')); - if(pr.isEmpty()) - product = QString("[%1]").arg(prid, 4, 16, QChar('0')); -} - -QList<SerialPortId> enumerateSerialPorts(int loglevel) -{ - QList<QString> eligibleInterfaces; - QList<InterfaceInfo> eligibleInterfacesInfo; - QList<SerialPortId> list; - - usb_init(); - usb_find_busses(); - usb_find_devices(); - - for (struct usb_bus *bus = usb_get_busses(); bus; bus = bus->next) { - for (struct usb_device *device = bus->devices; device; device = device->next) { - for (int n = 0; n < device->descriptor.bNumConfigurations && device->config; ++n) { - struct usb_config_descriptor &usbConfig =device->config[n]; - QList<int> usableInterfaces; - for (int m = 0; m < usbConfig.bNumInterfaces; ++m) { - for (int o = 0; o < usbConfig.interface[m].num_altsetting; ++o) { - struct usb_interface_descriptor &descriptor = usbConfig.interface[m].altsetting[o]; - if (descriptor.bInterfaceClass != 2 // "Communication" - || descriptor.bInterfaceSubClass != 2 // Abstract (modem) - || descriptor.bInterfaceProtocol != 255) // Vendor Specific - continue; - - unsigned char *buf = descriptor.extra; - unsigned int size = descriptor.extralen; - while (size >= 2 * sizeof(u_int8_t)) { - // for Communication devices there is a slave interface for the actual - // data transmission. - // the extra info stores that as a index for the interface - if (buf[0] >= 5 && buf[1] == 36 && buf[2] == 6) { // CDC Union - for (int i = 3; i < buf[0]; i++) - usableInterfaces.append((int) buf[i]); - } - size -= buf[0]; - buf += buf[0]; - } - } - } - - if (usableInterfaces.isEmpty()) - continue; - - QString manufacturerString; - QString productString; - - usb_dev_handle *devh = usb_open(device); - if (devh) { - QByteArray buf; - buf.resize(256); - int err = usb_get_string_simple(devh, device->descriptor.iManufacturer, buf.data(), buf.size()); - if (err < 0) { - if (loglevel > 1) - qDebug() << " can't read manufacturer name, error:" << err; - } else { - manufacturerString = QString::fromLatin1(buf); - if (loglevel > 1) - qDebug() << " manufacturer:" << manufacturerString; - } - - buf.resize(256); - err = usb_get_string_simple(devh, device->descriptor.iProduct, buf.data(), buf.size()); - if (err < 0) { - if (loglevel > 1) - qDebug() << " can't read product name, error:" << err; - } else { - productString = QString::fromLatin1(buf); - if (loglevel > 1) - qDebug() << " product:" << productString; - } - usb_close(devh); - } else if (loglevel > 0) { - qDebug() << " can't open usb device"; - } - - // second loop to find the actual data interface. - foreach (int i, usableInterfaces) { -#ifdef Q_OS_MAC - eligibleInterfaces << QString("^cu\\.usbmodem.*%1$") - .arg(QString("%1").arg(descriptor.bInterfaceNumber, 1, 16).toUpper()); -#else - // ### manufacturer and product strings are only readable as root :( - if (!manufacturerString.isEmpty() && !productString.isEmpty()) { - eligibleInterfaces << QString("usb-%1_%2-if%3") - .arg(manufacturerString.replace(QChar(' '), QChar('_'))) - .arg(productString.replace(QChar(' '), QChar('_'))) - .arg(i, 2, 16, QChar('0')); - } else { - eligibleInterfaces << QString("if%1").arg(i, 2, 16, QChar('0')); // fix! - } -#endif - } - eligibleInterfacesInfo << InterfaceInfo(manufacturerString, productString, device->descriptor.idVendor, device->descriptor.idProduct); - } - } - } - - if (loglevel > 1) - qDebug() << " searching for interfaces:" << eligibleInterfaces; - -#ifdef Q_OS_MAC - QDir dir("/dev/"); - bool allowAny = false; -#else - QDir dir("/dev/serial/by-id/"); - bool allowAny = eligibleInterfaces.isEmpty(); -#endif - foreach (const QFileInfo &info, dir.entryInfoList(QDir::System)) { - if (!info.isDir()) { - bool usable = allowAny; - QString friendlyName = info.fileName(); - foreach (const QString &iface, eligibleInterfaces) { - if (info.fileName().contains(QRegExp(iface))) { - if (loglevel > 1) - qDebug() << " found device file:" << info.fileName() << endl; -#ifdef Q_OS_MAC - friendlyName = eligibleInterfacesInfo[eligibleInterfaces.indexOf(iface)].product; -#endif - usable = true; - break; - } - } - if (!usable) - continue; - - SerialPortId id; - id.friendlyName = friendlyName; - id.portName = info.canonicalFilePath(); - list << id; - } - } - - if (list.isEmpty() && !eligibleInterfacesInfo.isEmpty() && loglevel > 0) { - qDebug() << "Possible USB devices found, but without serial drivers:"; - foreach(const InterfaceInfo &iface, eligibleInterfacesInfo) { - qDebug() << " Manufacturer:" - << iface.manufacturer - << "Product:" - << iface.product -#ifdef Q_OS_LINUX - << endl - << " Load generic driver using:" - << QString("sudo modprobe usbserial vendor=0x%1 product=0x%2") - .arg(iface.manufacturerid, 4, 16, QChar('0')) - .arg(iface.productid, 4, 16, QChar('0')); -#else - ; -#endif - } - } - return list; -} - diff --git a/src/runonphone/serenum_win.cpp b/src/runonphone/serenum_win.cpp deleted file mode 100644 index ad22bbde3..000000000 --- a/src/runonphone/serenum_win.cpp +++ /dev/null @@ -1,105 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the tools applications of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "serenum.h" -#include <QByteArray> -#include <QString> -#include <QDebug> -#include <windows.h> -#include <windef.h> -#include <setupapi.h> -#include <devguid.h> -#include <winreg.h> -#include <shlwapi.h> - -//{4d36e978-e325-11ce-bfc1-08002be10318} -//DEFINE_GUID(GUID_DEVCLASS_PORTS, 0x4D36E978, 0xE325, 0x11CE, 0xBF, 0xC1, 0x08, 0x00, 0x2B, 0xE1, 0x03, 0x18 ); - -QList<SerialPortId> enumerateSerialPorts(int) -{ - DWORD index=0; - SP_DEVINFO_DATA info; - GUID guid = GUID_DEVCLASS_PORTS; - HDEVINFO infoset = SetupDiGetClassDevs(&guid, 0, 0, DIGCF_PRESENT); - QString valueName(16384, 0); - QList<SerialPortId> list; - - for (index=0;;index++) { - ZeroMemory(&info, sizeof(SP_DEVINFO_DATA)); - info.cbSize = sizeof(SP_DEVINFO_DATA); - if (!SetupDiEnumDeviceInfo(infoset, index, &info)) - break; - QString friendlyName; - QString portName; - DWORD size=0; - SetupDiGetDeviceRegistryProperty(infoset, &info, SPDRP_FRIENDLYNAME, 0, 0, 0, &size); - QByteArray ba(size, 0); - if(SetupDiGetDeviceRegistryProperty(infoset, &info, SPDRP_FRIENDLYNAME, 0, (BYTE*)(ba.data()), size, 0)) { - friendlyName = QString((const QChar*)(ba.constData()), ba.size() / 2 - 1); - } - HKEY key = SetupDiOpenDevRegKey(infoset, &info, DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_READ); - if(key != INVALID_HANDLE_VALUE) { - //RegGetValue not supported on XP, SHRegGetValue not supported by mingw, so use the old method of enumerating all the values - for (DWORD dwi=0;;dwi++) { - DWORD vsize = valueName.size(); - if (ERROR_SUCCESS == RegEnumValue(key, dwi, (WCHAR*)(valueName.data()), &vsize, 0, 0, 0, &size)) { - if (valueName.startsWith("PortName")) { - QByteArray ba(size, 0); - vsize = valueName.size(); - if(ERROR_SUCCESS == RegEnumValue(key, dwi, (WCHAR*)(valueName.data()), &vsize, 0, 0, (BYTE*)(ba.data()), &size)) { - portName = QString((const QChar*)(ba.constData()), ba.size() / 2 - 1); - } - } - } else { - break; - } - } - RegCloseKey(key); - } - SerialPortId id; - id.portName = portName; - id.friendlyName = friendlyName; - list.append(id); - } - SetupDiDestroyDeviceInfoList(infoset); - return list; -} - diff --git a/src/runonphone/symbianutils/bluetoothlistener.cpp b/src/runonphone/symbianutils/bluetoothlistener.cpp deleted file mode 100644 index 7618327a1..000000000 --- a/src/runonphone/symbianutils/bluetoothlistener.cpp +++ /dev/null @@ -1,224 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the tools applications of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "bluetoothlistener.h" -#include "trkdevice.h" - -#include <QtCore/QDebug> - -#ifdef Q_OS_UNIX -# include <unistd.h> -# include <signal.h> -#else -# include <windows.h> -#endif - -// Process id helpers. -#ifdef Q_OS_WIN -inline DWORD processId(const QProcess &p) -{ - if (const Q_PID processInfoStruct = p.pid()) - return processInfoStruct->dwProcessId; - return 0; -} -#else -inline Q_PID processId(const QProcess &p) -{ - return p.pid(); -} -#endif - - -enum { debug = 0 }; - -namespace trk { - -struct BluetoothListenerPrivate { - BluetoothListenerPrivate(); - QString device; - QProcess process; -#ifdef Q_OS_WIN - DWORD pid; -#else - Q_PID pid; -#endif - bool printConsoleMessages; - BluetoothListener::Mode mode; -}; - -BluetoothListenerPrivate::BluetoothListenerPrivate() : - pid(0), - printConsoleMessages(false), - mode(BluetoothListener::Listen) -{ -} - -BluetoothListener::BluetoothListener(QObject *parent) : - QObject(parent), - d(new BluetoothListenerPrivate) -{ - d->process.setProcessChannelMode(QProcess::MergedChannels); - - connect(&d->process, SIGNAL(readyReadStandardError()), - this, SLOT(slotStdError())); - connect(&d->process, SIGNAL(readyReadStandardOutput()), - this, SLOT(slotStdOutput())); - connect(&d->process, SIGNAL(finished(int, QProcess::ExitStatus)), - this, SLOT(slotProcessFinished(int,QProcess::ExitStatus))); - connect(&d->process, SIGNAL(error(QProcess::ProcessError)), - this, SLOT(slotProcessError(QProcess::ProcessError))); -} - -BluetoothListener::~BluetoothListener() -{ - const int trc = terminateProcess(); - if (debug) - qDebug() << "~BluetoothListener: terminated" << trc; - delete d; -} - -BluetoothListener::Mode BluetoothListener::mode() const -{ - return d->mode; -} - -void BluetoothListener::setMode(Mode m) -{ - d->mode = m; -} - -bool BluetoothListener::printConsoleMessages() const -{ - return d->printConsoleMessages; -} - -void BluetoothListener::setPrintConsoleMessages(bool p) -{ - d->printConsoleMessages = p; -} - -int BluetoothListener::terminateProcess() -{ - enum { TimeOutMS = 200 }; - if (debug) - qDebug() << "terminateProcess" << d->process.pid() << d->process.state(); - if (d->process.state() == QProcess::NotRunning) - return -1; - emitMessage(tr("%1: Stopping listener %2...").arg(d->device).arg(processId(d->process))); - // When listening, the process should terminate by itself after closing the connection - if (mode() == Listen && d->process.waitForFinished(TimeOutMS)) - return 0; -#ifdef Q_OS_UNIX - kill(d->process.pid(), SIGHUP); // Listens for SIGHUP - if (d->process.waitForFinished(TimeOutMS)) - return 1; -#endif - d->process.terminate(); - if (d->process.waitForFinished(TimeOutMS)) - return 2; - d->process.kill(); - return 3; -} - -bool BluetoothListener::start(const QString &device, QString *errorMessage) -{ - if (d->process.state() != QProcess::NotRunning) { - *errorMessage = QLatin1String("Internal error: Still running."); - return false; - } - d->device = device; - const QString binary = QLatin1String("rfcomm"); - QStringList arguments; - arguments << QLatin1String("-r") - << (d->mode == Listen ? QLatin1String("listen") : QLatin1String("watch")) - << device << QString(QLatin1Char('1')); - if (debug) - qDebug() << binary << arguments; - emitMessage(tr("%1: Starting Bluetooth listener %2...").arg(device, binary)); - d->pid = 0; - d->process.start(binary, arguments); - if (!d->process.waitForStarted()) { - *errorMessage = tr("Unable to run '%1': %2").arg(binary, d->process.errorString()); - return false; - } - d->pid = processId(d->process); // Forgets it after crash/termination - emitMessage(tr("%1: Bluetooth listener running (%2).").arg(device).arg(processId(d->process))); - return true; -} - -void BluetoothListener::slotStdOutput() -{ - emitMessage(QString::fromLocal8Bit(d->process.readAllStandardOutput())); -} - -void BluetoothListener::emitMessage(const QString &m) -{ - if (d->printConsoleMessages || debug) - qDebug("%s\n", qPrintable(m)); - emit message(m); -} - -void BluetoothListener::slotStdError() -{ - emitMessage(QString::fromLocal8Bit(d->process.readAllStandardError())); -} - -void BluetoothListener::slotProcessFinished(int ex, QProcess::ExitStatus state) -{ - switch (state) { - case QProcess::NormalExit: - emitMessage(tr("%1: Process %2 terminated with exit code %3.") - .arg(d->device).arg(d->pid).arg(ex)); - break; - case QProcess::CrashExit: - emitMessage(tr("%1: Process %2 crashed.").arg(d->device).arg(d->pid)); - break; - } - emit terminated(); -} - -void BluetoothListener::slotProcessError(QProcess::ProcessError error) -{ - emitMessage(tr("%1: Process error %2: %3") - .arg(d->device).arg(error).arg(d->process.errorString())); -} - -} // namespace trk diff --git a/src/runonphone/symbianutils/bluetoothlistener.h b/src/runonphone/symbianutils/bluetoothlistener.h deleted file mode 100644 index b00d8270e..000000000 --- a/src/runonphone/symbianutils/bluetoothlistener.h +++ /dev/null @@ -1,103 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the tools applications of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef BLUETOOTHLISTENER_H -#define BLUETOOTHLISTENER_H - -#include "symbianutils_global.h" - -#include <QtCore/QObject> -#include <QtCore/QProcess> - -namespace trk { -struct BluetoothListenerPrivate; - -/* BluetoothListener: Starts a helper process watching connections on a - * Bluetooth device, Linux only: - * The rfcomm command is used. It process can be started in the background - * while connection attempts (TrkDevice::open()) are made in the foreground. */ - -class SYMBIANUTILS_EXPORT BluetoothListener : public QObject -{ - Q_OBJECT - Q_DISABLE_COPY(BluetoothListener) -public: - // The Mode property must be set before calling start(). - enum Mode { - Listen, /* Terminate after client closed (read: Trk app - * on the phone terminated or disconnected).*/ - Watch // Keep running, watch for next connection from client - }; - - explicit BluetoothListener(QObject *parent = 0); - virtual ~BluetoothListener(); - - Mode mode() const; - void setMode(Mode m); - - bool start(const QString &device, QString *errorMessage); - - // Print messages on the console. - bool printConsoleMessages() const; - void setPrintConsoleMessages(bool p); - -signals: - void terminated(); - void message(const QString &); - -public slots: - void emitMessage(const QString &m); // accessed by starter - -private slots: - void slotStdOutput(); - void slotStdError(); - void slotProcessFinished(int, QProcess::ExitStatus); - void slotProcessError(QProcess::ProcessError error); - -private: - int terminateProcess(); - - BluetoothListenerPrivate *d; -}; - -} // namespace trk - -#endif // BLUETOOTHLISTENER_H diff --git a/src/runonphone/symbianutils/bluetoothlistener_gui.cpp b/src/runonphone/symbianutils/bluetoothlistener_gui.cpp deleted file mode 100644 index 8855a2e15..000000000 --- a/src/runonphone/symbianutils/bluetoothlistener_gui.cpp +++ /dev/null @@ -1,111 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the tools applications of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "bluetoothlistener_gui.h" -#include "bluetoothlistener.h" -#include "communicationstarter.h" - -#include <QtWidgets/QMessageBox> -#include <QtWidgets/QPushButton> -#include <QtCore/QCoreApplication> -#include <QtCore/QDebug> - -namespace trk { - -SYMBIANUTILS_EXPORT PromptStartCommunicationResult - promptStartCommunication(BaseCommunicationStarter &starter, - const QString &msgBoxTitle, - const QString &msgBoxText, - QWidget *msgBoxParent, - QString *errorMessage) -{ - errorMessage->clear(); - // Initial connection attempt. - switch (starter.start()) { - case BaseCommunicationStarter::Started: - break; - case BaseCommunicationStarter::ConnectionSucceeded: - return PromptStartCommunicationConnected; - case BaseCommunicationStarter::StartError: - *errorMessage = starter.errorString(); - return PromptStartCommunicationError; - } - // Run the starter with the event loop of a message box, have the box - // closed by the signals of the starter. - QMessageBox messageBox(QMessageBox::Information, msgBoxTitle, msgBoxText, QMessageBox::Cancel, msgBoxParent); - QObject::connect(&starter, SIGNAL(connected()), &messageBox, SLOT(close())); - QObject::connect(&starter, SIGNAL(timeout()), &messageBox, SLOT(close())); - messageBox.exec(); - // Only starter.state() is reliable here to obtain the state. - switch (starter.state()) { - case AbstractBluetoothStarter::Running: - *errorMessage = QCoreApplication::translate("trk::promptStartCommunication", "Connection on %1 canceled.").arg(starter.device()); - return PromptStartCommunicationCanceled; - case AbstractBluetoothStarter::TimedOut: - *errorMessage = starter.errorString(); - return PromptStartCommunicationError; - case AbstractBluetoothStarter::Connected: - break; - } - return PromptStartCommunicationConnected; -} - -SYMBIANUTILS_EXPORT PromptStartCommunicationResult - promptStartSerial(BaseCommunicationStarter &starter, - QWidget *msgBoxParent, - QString *errorMessage) -{ - const QString title = QCoreApplication::translate("trk::promptStartCommunication", "Waiting for App TRK"); - const QString message = QCoreApplication::translate("trk::promptStartCommunication", "Waiting for App TRK to start on %1...").arg(starter.device()); - return promptStartCommunication(starter, title, message, msgBoxParent, errorMessage); -} - -SYMBIANUTILS_EXPORT PromptStartCommunicationResult - promptStartBluetooth(BaseCommunicationStarter &starter, - QWidget *msgBoxParent, - QString *errorMessage) -{ - const QString title = QCoreApplication::translate("trk::promptStartCommunication", "Waiting for Bluetooth Connection"); - const QString message = QCoreApplication::translate("trk::promptStartCommunication", "Connecting to %1...").arg(starter.device()); - return promptStartCommunication(starter, title, message, msgBoxParent, errorMessage); -} - -} // namespace trk diff --git a/src/runonphone/symbianutils/bluetoothlistener_gui.h b/src/runonphone/symbianutils/bluetoothlistener_gui.h deleted file mode 100644 index 522446c7a..000000000 --- a/src/runonphone/symbianutils/bluetoothlistener_gui.h +++ /dev/null @@ -1,89 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the tools applications of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef BLUETOOTHLISTENER_GUI_H -#define BLUETOOTHLISTENER_GUI_H - -#include "symbianutils_global.h" - -#include <QtCore/QtGlobal> - -QT_BEGIN_NAMESPACE -class QWidget; -QT_END_NAMESPACE - -namespace trk { -class BaseCommunicationStarter; - -/* promptStartCommunication(): Convenience functions that - * prompt the user to start a communication (launching or - * connecting TRK) using a modal message box in which they can cancel. - * Pass in the starter with device and parameters set up. */ - -enum PromptStartCommunicationResult { - PromptStartCommunicationConnected, - PromptStartCommunicationCanceled, - PromptStartCommunicationError -}; - -SYMBIANUTILS_EXPORT PromptStartCommunicationResult - promptStartCommunication(BaseCommunicationStarter &starter, - const QString &msgBoxTitle, - const QString &msgBoxText, - QWidget *msgBoxParent, - QString *errorMessage); - -// Convenience to start a serial connection (messages prompting -// to launch Trk). -SYMBIANUTILS_EXPORT PromptStartCommunicationResult - promptStartSerial(BaseCommunicationStarter &starter, - QWidget *msgBoxParent, - QString *errorMessage); - -// Convenience to start blue tooth connection (messages -// prompting to connect). -SYMBIANUTILS_EXPORT PromptStartCommunicationResult - promptStartBluetooth(BaseCommunicationStarter &starter, - QWidget *msgBoxParent, - QString *errorMessage); -} // namespace trk - -#endif // BLUETOOTHLISTENER_GUI_H diff --git a/src/runonphone/symbianutils/callback.h b/src/runonphone/symbianutils/callback.h deleted file mode 100644 index e44c15b69..000000000 --- a/src/runonphone/symbianutils/callback.h +++ /dev/null @@ -1,160 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the tools applications of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef DEBUGGER_CALLBACK_H -#define DEBUGGER_CALLBACK_H - -#include "symbianutils_global.h" - -namespace trk { -namespace Internal { - -/* Helper class for the 1-argument functor: - * Cloneable base class for the implementation which is - * invokeable with the argument. */ -template <class Argument> -class CallbackImplBase -{ - Q_DISABLE_COPY(CallbackImplBase) -public: - CallbackImplBase() {} - virtual CallbackImplBase *clone() const = 0; - virtual void invoke(Argument a) = 0; - virtual ~CallbackImplBase() {} -}; - -/* Helper class for the 1-argument functor: Implementation for - * a class instance with a member function pointer. */ -template <class Class, class Argument> -class CallbackMemberPtrImpl : public CallbackImplBase<Argument> -{ -public: - typedef void (Class::*MemberFuncPtr)(Argument); - - CallbackMemberPtrImpl(Class *instance, - MemberFuncPtr memberFunc) : - m_instance(instance), - m_memberFunc(memberFunc) {} - - virtual CallbackImplBase<Argument> *clone() const - { - return new CallbackMemberPtrImpl<Class, Argument>(m_instance, m_memberFunc); - } - - virtual void invoke(Argument a) - { (m_instance->*m_memberFunc)(a); } -private: - Class *m_instance; - MemberFuncPtr m_memberFunc; -}; - -} // namespace Internal - -/* Default-constructible, copyable 1-argument functor providing an - * operator()(Argument) that invokes a member function of a class: - * \code -class Foo { -public: - void print(const std::string &); -}; -... -Foo foo; -Callback<const std::string &> f1(&foo, &Foo::print); -f1("test"); -\endcode */ - -template <class Argument> -class Callback -{ -public: - Callback() : m_impl(0) {} - - template <class Class> - Callback(Class *instance, void (Class::*memberFunc)(Argument)) : - m_impl(new Internal::CallbackMemberPtrImpl<Class,Argument>(instance, memberFunc)) - {} - - ~Callback() - { - clean(); - } - - Callback(const Callback &rhs) : - m_impl(0) - { - if (rhs.m_impl) - m_impl = rhs.m_impl->clone(); - } - - Callback &operator=(const Callback &rhs) - { - if (this != &rhs) { - clean(); - if (rhs.m_impl) - m_impl = rhs.m_impl->clone(); - } - return *this; - } - - bool isNull() const { return m_impl == 0; } - operator bool() const { return !isNull(); } - - void operator()(Argument a) - { - if (m_impl) - m_impl->invoke(a); - } - -private: - void clean() - { - if (m_impl) { - delete m_impl; - m_impl = 0; - } - } - - Internal::CallbackImplBase<Argument> *m_impl; -}; - -} // namespace trk - -#endif // DEBUGGER_CALLBACK_H diff --git a/src/runonphone/symbianutils/communicationstarter.cpp b/src/runonphone/symbianutils/communicationstarter.cpp deleted file mode 100644 index 3a533529a..000000000 --- a/src/runonphone/symbianutils/communicationstarter.cpp +++ /dev/null @@ -1,251 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the tools applications of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "communicationstarter.h" -#include "bluetoothlistener.h" -#include "trkdevice.h" - -#include <QtCore/QTimer> -#include <QtCore/QEventLoop> - -namespace trk { - -// --------------- AbstractBluetoothStarter -struct BaseCommunicationStarterPrivate { - explicit BaseCommunicationStarterPrivate(const BaseCommunicationStarter::TrkDevicePtr &d); - - const BaseCommunicationStarter::TrkDevicePtr trkDevice; - BluetoothListener *listener; - QTimer *timer; - int intervalMS; - int attempts; - int n; - QString errorString; - BaseCommunicationStarter::State state; -}; - -BaseCommunicationStarterPrivate::BaseCommunicationStarterPrivate(const BaseCommunicationStarter::TrkDevicePtr &d) : - trkDevice(d), - listener(0), - timer(0), - intervalMS(1000), - attempts(-1), - n(0), - state(BaseCommunicationStarter::TimedOut) -{ -} - -BaseCommunicationStarter::BaseCommunicationStarter(const TrkDevicePtr &trkDevice, QObject *parent) : - QObject(parent), - d(new BaseCommunicationStarterPrivate(trkDevice)) -{ -} - -BaseCommunicationStarter::~BaseCommunicationStarter() -{ - stopTimer(); - delete d; -} - -void BaseCommunicationStarter::stopTimer() -{ - if (d->timer && d->timer->isActive()) - d->timer->stop(); -} - -bool BaseCommunicationStarter::initializeStartupResources(QString *errorMessage) -{ - errorMessage->clear(); - return true; -} - -BaseCommunicationStarter::StartResult BaseCommunicationStarter::start() -{ - if (state() == Running) { - d->errorString = QLatin1String("Internal error, attempt to re-start BaseCommunicationStarter.\n"); - return StartError; - } - // Before we instantiate timers, and such, try to open the device, - // which should succeed if another listener is already running in - // 'Watch' mode - if (d->trkDevice->open(&(d->errorString))) - return ConnectionSucceeded; - // Pull up resources for next attempt - d->n = 0; - if (!initializeStartupResources(&(d->errorString))) - return StartError; - // Start timer - if (!d->timer) { - d->timer = new QTimer; - connect(d->timer, SIGNAL(timeout()), this, SLOT(slotTimer())); - } - d->timer->setInterval(d->intervalMS); - d->timer->setSingleShot(false); - d->timer->start(); - d->state = Running; - return Started; -} - -BaseCommunicationStarter::State BaseCommunicationStarter::state() const -{ - return d->state; -} - -int BaseCommunicationStarter::intervalMS() const -{ - return d->intervalMS; -} - -void BaseCommunicationStarter::setIntervalMS(int i) -{ - d->intervalMS = i; - if (d->timer) - d->timer->setInterval(i); -} - -int BaseCommunicationStarter::attempts() const -{ - return d->attempts; -} - -void BaseCommunicationStarter::setAttempts(int a) -{ - d->attempts = a; -} - -QString BaseCommunicationStarter::device() const -{ - return d->trkDevice->port(); -} - -QString BaseCommunicationStarter::errorString() const -{ - return d->errorString; -} - -void BaseCommunicationStarter::slotTimer() -{ - ++d->n; - // Check for timeout - if (d->attempts >= 0 && d->n >= d->attempts) { - stopTimer(); - d->errorString = tr("%1: timed out after %n attempts using an interval of %2ms.", 0, d->n) - .arg(d->trkDevice->port()).arg(d->intervalMS); - d->state = TimedOut; - emit timeout(); - } else { - // Attempt n to connect? - if (d->trkDevice->open(&(d->errorString))) { - stopTimer(); - const QString msg = tr("%1: Connection attempt %2 succeeded.").arg(d->trkDevice->port()).arg(d->n); - emit message(msg); - d->state = Connected; - emit connected(); - } else { - const QString msg = tr("%1: Connection attempt %2 failed: %3 (retrying)...") - .arg(d->trkDevice->port()).arg(d->n).arg(d->errorString); - emit message(msg); - } - } -} - -// --------------- AbstractBluetoothStarter - -AbstractBluetoothStarter::AbstractBluetoothStarter(const TrkDevicePtr &trkDevice, QObject *parent) : - BaseCommunicationStarter(trkDevice, parent) -{ -} - -bool AbstractBluetoothStarter::initializeStartupResources(QString *errorMessage) -{ - // Create the listener and forward messages to it. - BluetoothListener *listener = createListener(); - connect(this, SIGNAL(message(QString)), listener, SLOT(emitMessage(QString))); - return listener->start(device(), errorMessage); -} - -// -------- ConsoleBluetoothStarter -ConsoleBluetoothStarter::ConsoleBluetoothStarter(const TrkDevicePtr &trkDevice, - QObject *listenerParent, - QObject *parent) : -AbstractBluetoothStarter(trkDevice, parent), -m_listenerParent(listenerParent) -{ -} - -BluetoothListener *ConsoleBluetoothStarter::createListener() -{ - BluetoothListener *rc = new BluetoothListener(m_listenerParent); - rc->setMode(BluetoothListener::Listen); - rc->setPrintConsoleMessages(true); - return rc; -} - -bool ConsoleBluetoothStarter::startBluetooth(const TrkDevicePtr &trkDevice, - QObject *listenerParent, - int attempts, - QString *errorMessage) -{ - // Set up a console starter to print to stdout. - ConsoleBluetoothStarter starter(trkDevice, listenerParent); - starter.setAttempts(attempts); - switch (starter.start()) { - case Started: - break; - case ConnectionSucceeded: - return true; - case StartError: - *errorMessage = starter.errorString(); - return false; - } - // Run the starter with an event loop. @ToDo: Implement - // some asynchronous keypress read to cancel. - QEventLoop eventLoop; - connect(&starter, SIGNAL(connected()), &eventLoop, SLOT(quit())); - connect(&starter, SIGNAL(timeout()), &eventLoop, SLOT(quit())); - eventLoop.exec(QEventLoop::ExcludeUserInputEvents); - if (starter.state() != AbstractBluetoothStarter::Connected) { - *errorMessage = starter.errorString(); - return false; - } - return true; -} -} // namespace trk diff --git a/src/runonphone/symbianutils/communicationstarter.h b/src/runonphone/symbianutils/communicationstarter.h deleted file mode 100644 index a653bd539..000000000 --- a/src/runonphone/symbianutils/communicationstarter.h +++ /dev/null @@ -1,160 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the tools applications of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef COMMUNICATIONSTARTER_H -#define COMMUNICATIONSTARTER_H - -#include "symbianutils_global.h" - -#include <QtCore/QSharedPointer> -#include <QtCore/QObject> - -namespace trk { -class TrkDevice; -class BluetoothListener; -struct BaseCommunicationStarterPrivate; - -/* BaseCommunicationStarter: A QObject that repeatedly tries to open a - * trk device until a connection succeeds or a timeout occurs (emitting - * signals), allowing to do something else in the foreground (local event loop - * [say QMessageBox] or some asynchronous operation). If the initial - * connection attempt in start() fails, the - * virtual initializeStartupResources() is called to initialize resources - * required to pull up the communication (namely Bluetooth listeners). - * The base class can be used as is to prompt the user to launch App TRK for a - * serial communication as this requires no further resource setup. */ - -class SYMBIANUTILS_EXPORT BaseCommunicationStarter : public QObject { - Q_OBJECT - Q_DISABLE_COPY(BaseCommunicationStarter) -public: - typedef QSharedPointer<TrkDevice> TrkDevicePtr; - - enum State { Running, Connected, TimedOut }; - - explicit BaseCommunicationStarter(const TrkDevicePtr& trkDevice, QObject *parent = 0); - virtual ~BaseCommunicationStarter(); - - int intervalMS() const; - void setIntervalMS(int i); - - int attempts() const; - void setAttempts(int a); - - QString device() const; - - State state() const; - QString errorString() const; - - enum StartResult { - Started, // Starter is now running. - ConnectionSucceeded, /* Initial connection attempt succeeded, - * no need to keep running. */ - StartError // Error occurred during start. - }; - - StartResult start(); - -signals: - void connected(); - void timeout(); - void message(const QString &); - -private slots: - void slotTimer(); - -protected: - virtual bool initializeStartupResources(QString *errorMessage); - -private: - inline void stopTimer(); - - BaseCommunicationStarterPrivate *d; -}; - -/* AbstractBluetoothStarter: Repeatedly tries to open a trk Bluetooth - * device. Note that in case a Listener is already running mode, the - * connection will succeed immediately. - * initializeStartupResources() is implemented to fire up the listener. - * Introduces a new virtual createListener() that derived classes must - * implement as a factory function that creates and sets up the - * listener (mode, message connection, etc). */ - -class SYMBIANUTILS_EXPORT AbstractBluetoothStarter : public BaseCommunicationStarter { - Q_OBJECT - Q_DISABLE_COPY(AbstractBluetoothStarter) -public: - -protected: - explicit AbstractBluetoothStarter(const TrkDevicePtr& trkDevice, QObject *parent = 0); - - // Implemented to fire up the listener. - virtual bool initializeStartupResources(QString *errorMessage); - // New virtual: Overwrite to create and parametrize the listener. - virtual BluetoothListener *createListener() = 0; -}; - -/* ConsoleBluetoothStarter: Convenience class for console processes. Creates a - * listener in "Listen" mode with the messages redirected to standard output. */ - -class SYMBIANUTILS_EXPORT ConsoleBluetoothStarter : public AbstractBluetoothStarter { - Q_OBJECT - Q_DISABLE_COPY(ConsoleBluetoothStarter) -public: - static bool startBluetooth(const TrkDevicePtr& trkDevice, - QObject *listenerParent, - int attempts, - QString *errorMessage); - -protected: - virtual BluetoothListener *createListener(); - -private: - explicit ConsoleBluetoothStarter(const TrkDevicePtr& trkDevice, - QObject *listenerParent, - QObject *parent = 0); - - QObject *m_listenerParent; -}; - -} // namespace trk - -#endif // COMMUNICATIONSTARTER_H diff --git a/src/runonphone/symbianutils/json.cpp b/src/runonphone/symbianutils/json.cpp deleted file mode 100644 index e8ad82784..000000000 --- a/src/runonphone/symbianutils/json.cpp +++ /dev/null @@ -1,490 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the tools applications of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "json.h" - -#ifdef TODO_USE_CREATOR -#include <utils/qtcassert.h> -#endif // TODO_USE_CREATOR - -#include <QtCore/QByteArray> -#include <QtCore/QTextStream> -#include <QtCore/QDebug> -#include <QtCore/QStringList> - -#include <ctype.h> - -//#define DEBUG_JASON -#ifdef DEBUG_JASON -#define JDEBUG(s) qDebug() << s -#else -#define JDEBUG(s) -#endif - -namespace tcftrk { - -static void skipSpaces(const char *&from, const char *to) -{ - while (from != to && isspace(*from)) - ++from; -} - -QTextStream &operator<<(QTextStream &os, const JsonValue &mi) -{ - return os << mi.toString(); -} - -void JsonValue::parsePair(const char *&from, const char *to) -{ - skipSpaces(from, to); - JDEBUG("parsePair: " << QByteArray(from, to - from)); - m_name = parseCString(from, to); - skipSpaces(from, to); - while (from < to && *from != ':') { - JDEBUG("not a colon" << *from); - ++from; - } - ++from; - parseValue(from, to); - skipSpaces(from, to); -} - -QByteArray JsonValue::parseNumber(const char *&from, const char *to) -{ - QByteArray result; - if (from < to && *from == '-') // Leading '-'. - result.append(*from++); - while (from < to && *from >= '0' && *from <= '9') - result.append(*from++); - return result; -} - -QByteArray JsonValue::parseCString(const char *&from, const char *to) -{ - QByteArray result; - JDEBUG("parseCString: " << QByteArray(from, to - from)); - if (*from != '"') { - qDebug() << "JSON Parse Error, double quote expected"; - ++from; // So we don't hang - return QByteArray(); - } - const char *ptr = from; - ++ptr; - while (ptr < to) { - if (*ptr == '"') { - ++ptr; - result = QByteArray(from + 1, ptr - from - 2); - break; - } - if (*ptr == '\\') { - ++ptr; - if (ptr == to) { - qDebug() << "JSON Parse Error, unterminated backslash escape"; - from = ptr; // So we don't hang - return QByteArray(); - } - } - ++ptr; - } - from = ptr; - - int idx = result.indexOf('\\'); - if (idx >= 0) { - char *dst = result.data() + idx; - const char *src = dst + 1, *end = result.data() + result.length(); - do { - char c = *src++; - switch (c) { - case 'a': *dst++ = '\a'; break; - case 'b': *dst++ = '\b'; break; - case 'f': *dst++ = '\f'; break; - case 'n': *dst++ = '\n'; break; - case 'r': *dst++ = '\r'; break; - case 't': *dst++ = '\t'; break; - case 'v': *dst++ = '\v'; break; - case '"': *dst++ = '"'; break; - case '\\': *dst++ = '\\'; break; - default: - { - int chars = 0; - uchar prod = 0; - forever { - if (c < '0' || c > '7') { - --src; - break; - } - prod = prod * 8 + c - '0'; - if (++chars == 3 || src == end) - break; - c = *src++; - } - if (!chars) { - qDebug() << "JSON Parse Error, unrecognized backslash escape"; - return QByteArray(); - } - *dst++ = prod; - } - } - while (src != end) { - char c = *src++; - if (c == '\\') - break; - *dst++ = c; - } - } while (src != end); - *dst = 0; - result.truncate(dst - result.data()); - } - - JDEBUG("parseCString, got " << result); - return result; -} - - - -void JsonValue::parseValue(const char *&from, const char *to) -{ - JDEBUG("parseValue: " << QByteArray(from, to - from)); - switch (*from) { - case '{': - parseObject(from, to); - break; - case 't': - if (to - from >= 4 && qstrncmp(from, "true", 4) == 0) { - m_data = QByteArray(from, 4); - from += m_data.size(); - m_type = Boolean; - } - break; - case 'f': - if (to - from >= 5 && qstrncmp(from, "false", 5) == 0) { - m_data = QByteArray(from, 5); - from += m_data.size(); - m_type = Boolean; - } - break; - case 'n': - if (to - from >= 4 && qstrncmp(from, "null", 4) == 0) { - m_data = QByteArray(from, 4); - from += m_data.size(); - m_type = NullObject; - } - break; - case '[': - parseArray(from, to); - break; - case '"': - m_type = String; - m_data = parseCString(from, to); - break; - case '0': case '1': case '2': case '3': case '4': - case '5': case '6': case '7': case '8': case '9': - case '-': - m_type = Number; - m_data = parseNumber(from, to); - default: - break; - } -} - -void JsonValue::parseObject(const char *&from, const char *to) -{ - JDEBUG("parseObject: " << QByteArray(from, to - from)); -#ifdef TODO_USE_CREATOR - QTC_ASSERT(*from == '{', /**/); -#endif - ++from; - m_type = Object; - while (from < to) { - if (*from == '}') { - ++from; - break; - } - JsonValue child; - child.parsePair(from, to); - if (!child.isValid()) - return; - m_children += child; - if (*from == ',') - ++from; - } -} - -void JsonValue::parseArray(const char *&from, const char *to) -{ - JDEBUG("parseArray: " << QByteArray(from, to - from)); -#ifdef TODO_USE_CREATOR - QTC_ASSERT(*from == '[', /**/); -#endif - ++from; - m_type = Array; - while (from < to) { - if (*from == ']') { - ++from; - break; - } - JsonValue child; - child.parseValue(from, to); - if (child.isValid()) - m_children += child; - if (*from == ',') - ++from; - } -} - -void JsonValue::setStreamOutput(const QByteArray &name, const QByteArray &content) -{ - if (content.isEmpty()) - return; - JsonValue child; - child.m_type = String; - child.m_name = name; - child.m_data = content; - m_children += child; - if (m_type == Invalid) - m_type = Object; -} - -static QByteArray ind(int indent) -{ - return QByteArray(2 * indent, ' '); -} - -void JsonValue::dumpChildren(QByteArray * str, bool multiline, int indent) const -{ - for (int i = 0; i < m_children.size(); ++i) { - if (i != 0) { - *str += ','; - if (multiline) - *str += '\n'; - } - if (multiline) - *str += ind(indent); - *str += m_children.at(i).toString(multiline, indent); - } -} - -class MyString : public QString { -public: - ushort at(int i) const { return constData()[i].unicode(); } -}; - -template<class ST, typename CT> -inline ST escapeCStringTpl(const ST &ba) -{ - ST ret; - ret.reserve(ba.length() * 2); - for (int i = 0; i < ba.length(); ++i) { - CT c = ba.at(i); - switch (c) { - case '\\': ret += "\\\\"; break; - case '\a': ret += "\\a"; break; - case '\b': ret += "\\b"; break; - case '\f': ret += "\\f"; break; - case '\n': ret += "\\n"; break; - case '\r': ret += "\\r"; break; - case '\t': ret += "\\t"; break; - case '\v': ret += "\\v"; break; - case '"': ret += "\\\""; break; - default: - if (c < 32 || c == 127) { - ret += '\\'; - ret += '0' + (c >> 6); - ret += '0' + ((c >> 3) & 7); - ret += '0' + (c & 7); - } else { - ret += c; - } - } - } - return ret; -} - -QString JsonValue::escapeCString(const QString &ba) -{ - return escapeCStringTpl<MyString, ushort>(static_cast<const MyString &>(ba)); -} - -QByteArray JsonValue::escapeCString(const QByteArray &ba) -{ - return escapeCStringTpl<QByteArray, uchar>(ba); -} - -QByteArray JsonValue::toString(bool multiline, int indent) const -{ - QByteArray result; - switch (m_type) { - case Invalid: - if (multiline) - result += ind(indent) + "Invalid\n"; - else - result += "Invalid"; - break; - case String: - if (!m_name.isEmpty()) - result += m_name + "="; - result += '"' + escapeCString(m_data) + '"'; - break; - case Number: - if (!m_name.isEmpty()) - result += '"' + m_name + "\":"; - result += m_data; - break; - case Boolean: - case NullObject: - if (!m_name.isEmpty()) - result += '"' + m_name + "\":"; - result += m_data; - break; - case Object: - if (!m_name.isEmpty()) - result += m_name + '='; - if (multiline) { - result += "{\n"; - dumpChildren(&result, multiline, indent + 1); - result += '\n' + ind(indent) + "}"; - } else { - result += "{"; - dumpChildren(&result, multiline, indent + 1); - result += "}"; - } - break; - case Array: - if (!m_name.isEmpty()) - result += m_name + "="; - if (multiline) { - result += "[\n"; - dumpChildren(&result, multiline, indent + 1); - result += '\n' + ind(indent) + "]"; - } else { - result += "["; - dumpChildren(&result, multiline, indent + 1); - result += "]"; - } - break; - } - return result; -} - -void JsonValue::fromString(const QByteArray &ba) -{ - const char *from = ba.constBegin(); - const char *to = ba.constEnd(); - parseValue(from, to); -} - -JsonValue JsonValue::findChild(const char *name) const -{ - for (int i = 0; i < m_children.size(); ++i) - if (m_children.at(i).m_name == name) - return m_children.at(i); - return JsonValue(); -} - -void JsonInputStream::appendCString(const char *s) -{ - m_target.append('"'); - for (const char *p = s; *p; p++) { - if (*p == '"' || *p == '\\') - m_target.append('\\'); - m_target.append(*p); - } - m_target.append('"'); -} - -void JsonInputStream::appendString(const QString &in) -{ - if (in.isEmpty()) { - m_target.append("\"\""); - return; - } - - const QChar doubleQuote('"'); - const QChar backSlash('\\'); - QString rc; - const int inSize = in.size(); - rc.reserve(in.size() + 5); - rc.append(doubleQuote); - for (int i = 0; i < inSize; i++) { - const QChar c = in.at(i); - if (c == doubleQuote || c == backSlash) - rc.append(backSlash); - rc.append(c); - } - rc.append(doubleQuote); - m_target.append(rc.toUtf8()); - return; -} - -JsonInputStream &JsonInputStream::operator<<(const QStringList &in) -{ - m_target.append('['); - const int count = in.size(); - for (int i = 0 ; i < count; i++) { - if (i) - m_target.append(','); - appendString(in.at(i)); - } - m_target.append(']'); - return *this; -} - -JsonInputStream &JsonInputStream::operator<<(const QVector<QByteArray> &ba) -{ - m_target.append('['); - const int count = ba.size(); - for (int i = 0 ; i < count; i++) { - if (i) - m_target.append(','); - appendCString(ba.at(i).constData()); - } - m_target.append(']'); - return *this; -} - -JsonInputStream &JsonInputStream::operator<<(bool b) -{ - m_target.append(b ? "true" : "false"); - return *this; -} - -} // namespace tcftrk - diff --git a/src/runonphone/symbianutils/json.h b/src/runonphone/symbianutils/json.h deleted file mode 100644 index 7cf2575f3..000000000 --- a/src/runonphone/symbianutils/json.h +++ /dev/null @@ -1,149 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the tools applications of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef SYMBIANUTILS_JSON_H -#define SYMBIANUTILS_JSON_H - -#include "symbianutils_global.h" - -#include <QtCore/QByteArray> -#include <QtCore/QStringList> -#include <QtCore/QVector> - -namespace tcftrk { - -class SYMBIANUTILS_EXPORT JsonValue -{ -public: - JsonValue() : m_type(Invalid) {} - explicit JsonValue(const QByteArray &str) { fromString(str); } - - QByteArray m_name; - QByteArray m_data; - QList<JsonValue> m_children; - - enum Type { - Invalid, - String, - Number, - Boolean, - Object, - NullObject, - Array, - }; - - Type m_type; - - inline Type type() const { return m_type; } - inline QByteArray name() const { return m_name; } - inline bool hasName(const char *name) const { return m_name == name; } - - inline bool isValid() const { return m_type != Invalid; } - inline bool isNumber() const { return m_type == Number; } - inline bool isString() const { return m_type == String; } - inline bool isObject() const { return m_type == Object; } - inline bool isArray() const { return m_type == Array; } - - - inline QByteArray data() const { return m_data; } - inline const QList<JsonValue> &children() const { return m_children; } - inline int childCount() const { return m_children.size(); } - - const JsonValue &childAt(int index) const { return m_children[index]; } - JsonValue &childAt(int index) { return m_children[index]; } - JsonValue findChild(const char *name) const; - - QByteArray toString(bool multiline = false, int indent = 0) const; - void fromString(const QByteArray &str); - void setStreamOutput(const QByteArray &name, const QByteArray &content); - -private: - static QByteArray parseCString(const char *&from, const char *to); - static QByteArray parseNumber(const char *&from, const char *to); - static QByteArray escapeCString(const QByteArray &ba); - static QString escapeCString(const QString &ba); - void parsePair(const char *&from, const char *to); - void parseValue(const char *&from, const char *to); - void parseObject(const char *&from, const char *to); - void parseArray(const char *&from, const char *to); - - void dumpChildren(QByteArray *str, bool multiline, int indent) const; -}; - -/* Thin wrapper around QByteArray for formatting JSON input. Use as in: - * JsonInputStream(byteArray) << '{' << "bla" << ':' << "blup" << '}'; - * Note that strings get double quotes and JSON-escaping, characters should be - * used for the array/hash delimiters. - * */ -class SYMBIANUTILS_EXPORT JsonInputStream { -public: - explicit JsonInputStream(QByteArray &a) : m_target(a) {} - - JsonInputStream &operator<<(char c) { m_target.append(c); return *this; } - JsonInputStream &operator<<(const char *c) { appendCString(c); return *this; } - JsonInputStream &operator<<(const QByteArray &a) { appendCString(a.constData()); return *this; } - JsonInputStream &operator<<(const QString &c) { appendString(c); return *this; } - - // Format as array - JsonInputStream &operator<<(const QStringList &c); - - // Format as array - JsonInputStream &operator<<(const QVector<QByteArray> &ba); - - JsonInputStream &operator<<(bool b); - - JsonInputStream &operator<<(int i) - { m_target.append(QByteArray::number(i)); return *this; } - JsonInputStream &operator<<(unsigned i) - { m_target.append(QByteArray::number(i)); return *this; } - JsonInputStream &operator<<(quint64 i) - { m_target.append(QByteArray::number(i)); return *this; } - -private: - void appendString(const QString &); - void appendCString(const char *c); - - QByteArray &m_target; -}; - -} // namespace tcftrk - -#endif // SYMBIANUTILS_JSON_H diff --git a/src/runonphone/symbianutils/launcher.cpp b/src/runonphone/symbianutils/launcher.cpp deleted file mode 100644 index f07867d48..000000000 --- a/src/runonphone/symbianutils/launcher.cpp +++ /dev/null @@ -1,1036 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the tools applications of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "launcher.h" -#include "trkutils.h" -#include "trkutils_p.h" -#include "trkdevice.h" -#include "bluetoothlistener.h" -#include "symbiandevicemanager.h" - -#include <QtCore/QTimer> -#include <QtCore/QDateTime> -#include <QtCore/QVariant> -#include <QtCore/QDebug> -#include <QtCore/QQueue> -#include <QtCore/QFile> -#include <QtCore/QScopedPointer> - -#include <cstdio> - -namespace trk { - -struct CrashReportState { - CrashReportState(); - void clear(); - - typedef uint Thread; - typedef QList<Thread> Threads; - Threads threads; - - QList<uint> registers; - QByteArray stack; - uint sp; - uint fetchingStackPID; - uint fetchingStackTID; -}; - -CrashReportState::CrashReportState() -{ - clear(); -} - -void CrashReportState::clear() -{ - threads.clear(); - stack.clear(); - sp = fetchingStackPID = fetchingStackTID = 0; -} - -struct LauncherPrivate { - struct CopyState { - QString sourceFileName; - QString destinationFileName; - uint copyFileHandle; - QScopedPointer<QByteArray> data; - qint64 position; - QScopedPointer<QFile> localFile; - }; - - explicit LauncherPrivate(const TrkDevicePtr &d); - - TrkDevicePtr m_device; - QByteArray m_trkReadBuffer; - Launcher::State m_state; - - void logMessage(const QString &msg); - // Debuggee state - Session m_session; // global-ish data (process id, target information) - - CopyState m_copyState; - CopyState m_downloadState; - QString m_fileName; - QStringList m_commandLineArgs; - QString m_installFileName; - int m_verbose; - Launcher::Actions m_startupActions; - bool m_closeDevice; - CrashReportState m_crashReportState; -}; - -LauncherPrivate::LauncherPrivate(const TrkDevicePtr &d) : - m_device(d), - m_state(Launcher::Disconnected), - m_verbose(0), - m_closeDevice(true) -{ - if (m_device.isNull()) - m_device = TrkDevicePtr(new TrkDevice); -} - -Launcher::Launcher(Actions startupActions, - const TrkDevicePtr &dev, - QObject *parent) : - QObject(parent), - d(new LauncherPrivate(dev)) -{ - d->m_startupActions = startupActions; - connect(d->m_device.data(), SIGNAL(messageReceived(trk::TrkResult)), this, SLOT(handleResult(trk::TrkResult))); -} - -Launcher::~Launcher() -{ - // Destroyed before protocol was through: Close - if (d->m_closeDevice && d->m_device->isOpen()) - d->m_device->close(); - emit destroyed(d->m_device->port()); - logMessage("Shutting down.\n"); - delete d; -} - -Launcher::State Launcher::state() const -{ - return d->m_state; -} - -void Launcher::setState(State s) -{ - if (s != d->m_state) { - d->m_state = s; - emit stateChanged(s); - } -} - -void Launcher::addStartupActions(trk::Launcher::Actions startupActions) -{ - d->m_startupActions = Actions(d->m_startupActions | startupActions); -} - -void Launcher::setTrkServerName(const QString &name) -{ - d->m_device->setPort(name); -} - -QString Launcher::trkServerName() const -{ - return d->m_device->port(); -} - -TrkDevicePtr Launcher::trkDevice() const -{ - return d->m_device; -} - -void Launcher::setFileName(const QString &name) -{ - d->m_fileName = name; -} - -void Launcher::setCopyFileName(const QString &srcName, const QString &dstName) -{ - d->m_copyState.sourceFileName = srcName; - d->m_copyState.destinationFileName = dstName; -} - -void Launcher::setDownloadFileName(const QString &srcName, const QString &dstName) -{ - d->m_downloadState.sourceFileName = srcName; - d->m_downloadState.destinationFileName = dstName; -} - -void Launcher::setInstallFileName(const QString &name) -{ - d->m_installFileName = name; -} - -void Launcher::setCommandLineArgs(const QStringList &args) -{ - d->m_commandLineArgs = args; -} - -void Launcher::setSerialFrame(bool b) -{ - d->m_device->setSerialFrame(b); -} - -bool Launcher::serialFrame() const -{ - return d->m_device->serialFrame(); -} - - -bool Launcher::closeDevice() const -{ - return d->m_closeDevice; -} - -void Launcher::setCloseDevice(bool c) -{ - d->m_closeDevice = c; -} - -bool Launcher::startServer(QString *errorMessage) -{ - errorMessage->clear(); - d->m_crashReportState.clear(); - if (d->m_verbose) { - QString msg; - QTextStream str(&msg); - str.setIntegerBase(16); - str << "Actions=0x" << d->m_startupActions; - str.setIntegerBase(10); - str << " Port=" << trkServerName(); - if (!d->m_fileName.isEmpty()) - str << " Executable=" << d->m_fileName; - if (!d->m_commandLineArgs.isEmpty()) - str << " Arguments= " << d->m_commandLineArgs.join(QString(QLatin1Char(' '))); - if (!d->m_copyState.sourceFileName.isEmpty()) - str << " Package/Source=" << d->m_copyState.sourceFileName; - if (!d->m_copyState.destinationFileName.isEmpty()) - str << " Remote Package/Destination=" << d->m_copyState.destinationFileName; - if (!d->m_downloadState.sourceFileName.isEmpty()) - str << " Source=" << d->m_downloadState.sourceFileName; - if (!d->m_downloadState.destinationFileName.isEmpty()) - str << " Destination=" << d->m_downloadState.destinationFileName; - if (!d->m_installFileName.isEmpty()) - str << " Install file=" << d->m_installFileName; - logMessage(msg); - } - if (d->m_startupActions & ActionCopy) { - if (d->m_copyState.sourceFileName.isEmpty()) { - qWarning("No local filename given for copying package."); - return false; - } else if (d->m_copyState.destinationFileName.isEmpty()) { - qWarning("No remote filename given for copying package."); - return false; - } - } - if (d->m_startupActions & ActionInstall && d->m_installFileName.isEmpty()) { - qWarning("No package name given for installing."); - return false; - } - if (d->m_startupActions & ActionRun && d->m_fileName.isEmpty()) { - qWarning("No remote executable given for running."); - return false; - } - if (!d->m_device->isOpen() && !d->m_device->open(errorMessage)) - return false; - setState(Connecting); - // Set up the temporary 'waiting' state if we do not get immediate connection - QTimer::singleShot(1000, this, SLOT(slotWaitingForTrk())); - d->m_device->sendTrkInitialPing(); - d->m_device->sendTrkMessage(TrkDisconnect); // Disconnect, as trk might be still connected - d->m_device->sendTrkMessage(TrkSupported, TrkCallback(this, &Launcher::handleSupportMask)); - d->m_device->sendTrkMessage(TrkCpuType, TrkCallback(this, &Launcher::handleCpuType)); - d->m_device->sendTrkMessage(TrkVersions, TrkCallback(this, &Launcher::handleTrkVersion)); - if (d->m_startupActions != ActionPingOnly) - d->m_device->sendTrkMessage(TrkConnect, TrkCallback(this, &Launcher::handleConnect)); - return true; -} - -void Launcher::slotWaitingForTrk() -{ - // Set temporary state if we are still in connected state - if (state() == Connecting) - setState(WaitingForTrk); -} - -void Launcher::handleConnect(const TrkResult &result) -{ - if (result.errorCode()) { - emit canNotConnect(result.errorString()); - return; - } - setState(Connected); - if (d->m_startupActions & ActionCopy) - copyFileToRemote(); - else if (d->m_startupActions & ActionInstall) - installRemotePackageSilently(); - else if (d->m_startupActions & ActionRun) - startInferiorIfNeeded(); - else if (d->m_startupActions & ActionDownload) - copyFileFromRemote(); -} - -void Launcher::setVerbose(int v) -{ - d->m_verbose = v; - d->m_device->setVerbose(v); -} - -void Launcher::logMessage(const QString &msg) -{ - if (d->m_verbose) - qDebug() << "LAUNCHER: " << qPrintable(msg); -} - -void Launcher::handleFinished() -{ - if (d->m_closeDevice) - d->m_device->close(); - emit finished(); -} - -void Launcher::terminate() -{ - switch (state()) { - case DeviceDescriptionReceived: - case Connected: - if (d->m_session.pid) { - QByteArray ba; - appendShort(&ba, 0x0000, TargetByteOrder); - appendInt(&ba, d->m_session.pid, TargetByteOrder); - d->m_device->sendTrkMessage(TrkDeleteItem, TrkCallback(this, &Launcher::handleRemoteProcessKilled), ba); - return; - } - if (d->m_copyState.copyFileHandle) - closeRemoteFile(true); - disconnectTrk(); - break; - case Disconnected: - break; - case Connecting: - case WaitingForTrk: - setState(Disconnected); - handleFinished(); - break; - } -} - -void Launcher::handleRemoteProcessKilled(const TrkResult &result) -{ - Q_UNUSED(result) - disconnectTrk(); -} - -QString Launcher::msgStopped(uint pid, uint tid, uint address, const QString &why) -{ - return QString::fromLatin1("Process %1, thread %2 stopped at 0x%3: %4"). - arg(pid).arg(tid).arg(address, 0, 16). - arg(why.isEmpty() ? QString::fromLatin1("<Unknown reason>") : why); -} - -bool Launcher::parseNotifyStopped(const QByteArray &dataBA, - uint *pid, uint *tid, uint *address, - QString *why /* = 0 */) -{ - if (why) - why->clear(); - *address = *pid = *tid = 0; - if (dataBA.size() < 12) - return false; - const char *data = dataBA.data(); - *address = extractInt(data); - *pid = extractInt(data + 4); - *tid = extractInt(data + 8); - if (why && dataBA.size() >= 14) { - const unsigned short len = extractShort(data + 12); - if (len > 0) - *why = QString::fromLatin1(data + 14, len); - } - return true; -} - -void Launcher::handleResult(const TrkResult &result) -{ - QByteArray prefix = "READ BUF: "; - QByteArray str = result.toString().toUtf8(); - if (result.isDebugOutput) { // handle application output - QString msg; - if (result.multiplex == MuxTextTrace) { - if (result.data.length() > 8) { - quint64 timestamp = extractInt64(result.data) & 0x0FFFFFFFFFFFFFFFULL; - quint64 secs = timestamp / 1000000000; - quint64 ns = timestamp % 1000000000; - msg = QString("[%1.%2] %3").arg(secs).arg(ns).arg(QString(result.data.mid(8))); - logMessage("TEXT TRACE: " + msg); - } - } else { - logMessage("APPLICATION OUTPUT: " + stringFromArray(result.data)); - msg = result.data; - } - msg.replace("\r\n", "\n"); - if(!msg.endsWith('\n')) msg.append('\n'); - emit applicationOutputReceived(msg); - return; - } - switch (result.code) { - case TrkNotifyAck: - break; - case TrkNotifyNak: { // NAK - logMessage(prefix + "NAK: " + str); - //logMessage(prefix << "TOKEN: " << result.token); - logMessage(prefix + "ERROR: " + errorMessage(result.data.at(0))); - break; - } - case TrkNotifyStopped: { // Notified Stopped - QString reason; - uint pc; - uint pid; - uint tid; - parseNotifyStopped(result.data, &pid, &tid, &pc, &reason); - logMessage(prefix + msgStopped(pid, tid, pc, reason)); - emit(processStopped(pc, pid, tid, reason)); - d->m_device->sendTrkAck(result.token); - break; - } - case TrkNotifyException: { // Notify Exception (obsolete) - logMessage(prefix + "NOTE: EXCEPTION " + str); - d->m_device->sendTrkAck(result.token); - break; - } - case TrkNotifyInternalError: { // - logMessage(prefix + "NOTE: INTERNAL ERROR: " + str); - d->m_device->sendTrkAck(result.token); - break; - } - - // target->host OS notification - case TrkNotifyCreated: { // Notify Created - - if (result.data.size() < 10) - break; - const char *data = result.data.constData(); - const byte error = result.data.at(0); - Q_UNUSED(error) - const byte type = result.data.at(1); // type: 1 byte; for dll item, this value is 2. - const uint tid = extractInt(data + 6); //threadID: 4 bytes - Q_UNUSED(tid) - if (type == kDSOSDLLItem && result.data.size() >=20) { - const Library lib = Library(result); - d->m_session.libraries.push_back(lib); - emit libraryLoaded(lib); - } - QByteArray ba; - ba.append(result.data.mid(2, 8)); - d->m_device->sendTrkMessage(TrkContinue, TrkCallback(), ba, "CONTINUE"); - break; - } - case TrkNotifyDeleted: { // NotifyDeleted - const ushort itemType = (unsigned char)result.data.at(1); - const uint pid = result.data.size() >= 6 ? extractShort(result.data.constData() + 2) : 0; - const uint tid = result.data.size() >= 10 ? extractShort(result.data.constData() + 6) : 0; - Q_UNUSED(tid) - const ushort len = result.data.size() > 12 ? extractShort(result.data.constData() + 10) : ushort(0); - const QString name = len ? QString::fromLatin1(result.data.mid(12, len)) : QString(); - logMessage(QString::fromLatin1("%1 %2 UNLOAD: %3"). - arg(QString::fromLatin1(prefix)).arg(itemType ? QLatin1String("LIB") : QLatin1String("PROCESS")). - arg(name)); - d->m_device->sendTrkAck(result.token); - if (itemType == kDSOSProcessItem // process - && result.data.size() >= 10 - && d->m_session.pid == extractInt(result.data.data() + 6)) { - if (d->m_startupActions & ActionDownload) - copyFileFromRemote(); - else - disconnectTrk(); - } - else if (itemType == kDSOSDLLItem && len) { - // Remove libraries of process. - for (QList<Library>::iterator it = d->m_session.libraries.begin(); it != d->m_session.libraries.end(); ) { - if ((*it).pid == pid && (*it).name == name) { - emit libraryUnloaded(*it); - it = d->m_session.libraries.erase(it); - } else { - ++it; - } - } - } - break; - } - case TrkNotifyProcessorStarted: { // NotifyProcessorStarted - logMessage(prefix + "NOTE: PROCESSOR STARTED: " + str); - d->m_device->sendTrkAck(result.token); - break; - } - case TrkNotifyProcessorStandBy: { // NotifyProcessorStandby - logMessage(prefix + "NOTE: PROCESSOR STANDBY: " + str); - d->m_device->sendTrkAck(result.token); - break; - } - case TrkNotifyProcessorReset: { // NotifyProcessorReset - logMessage(prefix + "NOTE: PROCESSOR RESET: " + str); - d->m_device->sendTrkAck(result.token); - break; - } - default: { - logMessage(prefix + "INVALID: " + str); - break; - } - } -} - -QString Launcher::deviceDescription(unsigned verbose) const -{ - return d->m_session.deviceDescription(verbose); -} - -void Launcher::handleTrkVersion(const TrkResult &result) -{ - if (result.errorCode() || result.data.size() < 5) { - if (d->m_startupActions == ActionPingOnly) { - setState(Disconnected); - handleFinished(); - } - return; - } - d->m_session.trkAppVersion.trkMajor = result.data.at(1); - d->m_session.trkAppVersion.trkMinor = result.data.at(2); - d->m_session.trkAppVersion.protocolMajor = result.data.at(3); - d->m_session.trkAppVersion.protocolMinor = result.data.at(4); - setState(DeviceDescriptionReceived); - const QString msg = deviceDescription(); - emit deviceDescriptionReceived(trkServerName(), msg); - // Ping mode: Log & Terminate - if (d->m_startupActions == ActionPingOnly) { - qWarning("%s", qPrintable(msg)); - setState(Disconnected); - handleFinished(); - } -} - -static inline QString msgCannotOpenRemoteFile(const QString &fileName, const QString &message) -{ - return Launcher::tr("Cannot open remote file '%1': %2").arg(fileName, message); -} - -static inline QString msgCannotOpenLocalFile(const QString &fileName, const QString &message) -{ - return Launcher::tr("Cannot open '%1': %2").arg(fileName, message); -} - -void Launcher::handleFileCreation(const TrkResult &result) -{ - if (result.errorCode() || result.data.size() < 6) { - const QString msg = msgCannotOpenRemoteFile(d->m_copyState.destinationFileName, result.errorString()); - logMessage(msg); - emit canNotCreateFile(d->m_copyState.destinationFileName, msg); - disconnectTrk(); - return; - } - const char *data = result.data.data(); - d->m_copyState.copyFileHandle = extractInt(data + 2); - const QString localFileName = d->m_copyState.sourceFileName; - QFile file(localFileName); - d->m_copyState.position = 0; - if (!file.open(QIODevice::ReadOnly)) { - const QString msg = msgCannotOpenLocalFile(localFileName, file.errorString()); - logMessage(msg); - emit canNotOpenLocalFile(localFileName, msg); - closeRemoteFile(true); - disconnectTrk(); - return; - } - d->m_copyState.data.reset(new QByteArray(file.readAll())); - file.close(); - continueCopying(); -} - -void Launcher::handleFileOpened(const TrkResult &result) -{ - if (result.errorCode() || result.data.size() < 6) { - const QString msg = msgCannotOpenRemoteFile(d->m_downloadState.sourceFileName, result.errorString()); - logMessage(msg); - emit canNotOpenFile(d->m_downloadState.sourceFileName, msg); - disconnectTrk(); - return; - } - d->m_downloadState.position = 0; - const QString localFileName = d->m_downloadState.destinationFileName; - bool opened = false; - if (localFileName == QLatin1String("-")) { - d->m_downloadState.localFile.reset(new QFile); - opened = d->m_downloadState.localFile->open(stdout, QFile::WriteOnly); - } else { - d->m_downloadState.localFile.reset(new QFile(localFileName)); - opened = d->m_downloadState.localFile->open(QFile::WriteOnly | QFile::Truncate); - } - if (!opened) { - const QString msg = msgCannotOpenLocalFile(localFileName, d->m_downloadState.localFile->errorString()); - logMessage(msg); - emit canNotOpenLocalFile(localFileName, msg); - closeRemoteFile(true); - disconnectTrk(); - } - continueReading(); -} - -void Launcher::continueReading() -{ - QByteArray ba; - appendInt(&ba, d->m_downloadState.copyFileHandle, TargetByteOrder); - appendShort(&ba, 2048, TargetByteOrder); - d->m_device->sendTrkMessage(TrkReadFile, TrkCallback(this, &Launcher::handleRead), ba); -} - -void Launcher::handleRead(const TrkResult &result) -{ - if (result.errorCode() || result.data.size() < 4) { - d->m_downloadState.localFile->close(); - closeRemoteFile(true); - disconnectTrk(); - } else { - int length = extractShort(result.data.data() + 2); - //TRK doesn't tell us the file length, so we need to keep reading until it returns 0 length - if (length > 0) { - d->m_downloadState.localFile->write(result.data.data() + 4, length); - continueReading(); - } else { - closeRemoteFile(true); - disconnectTrk(); - } - } -} - -void Launcher::handleCopy(const TrkResult &result) -{ - if (result.errorCode() || result.data.size() < 4) { - closeRemoteFile(true); - emit canNotWriteFile(d->m_copyState.destinationFileName, result.errorString()); - disconnectTrk(); - } else { - continueCopying(extractShort(result.data.data() + 2)); - } -} - -void Launcher::continueCopying(uint lastCopiedBlockSize) -{ - qint64 size = d->m_copyState.data->length(); - d->m_copyState.position += lastCopiedBlockSize; - if (size == 0) - emit copyProgress(100); - else { - const qint64 hundred = 100; - const qint64 percent = qMin( (d->m_copyState.position * hundred) / size, hundred); - emit copyProgress(static_cast<int>(percent)); - } - if (d->m_copyState.position < size) { - QByteArray ba; - appendInt(&ba, d->m_copyState.copyFileHandle, TargetByteOrder); - appendString(&ba, d->m_copyState.data->mid(d->m_copyState.position, 2048), TargetByteOrder, false); - d->m_device->sendTrkMessage(TrkWriteFile, TrkCallback(this, &Launcher::handleCopy), ba); - } else { - closeRemoteFile(); - } -} - -void Launcher::closeRemoteFile(bool failed) -{ - QByteArray ba; - appendInt(&ba, d->m_copyState.copyFileHandle, TargetByteOrder); - appendDateTime(&ba, QDateTime::currentDateTime(), TargetByteOrder); - d->m_device->sendTrkMessage(TrkCloseFile, - failed ? TrkCallback() : TrkCallback(this, &Launcher::handleFileCopied), - ba); - d->m_copyState.data.reset(); - d->m_copyState.copyFileHandle = 0; - d->m_copyState.position = 0; -} - -void Launcher::handleFileCopied(const TrkResult &result) -{ - if (result.errorCode()) - emit canNotCloseFile(d->m_copyState.destinationFileName, result.errorString()); - if (d->m_startupActions & ActionInstall) - installRemotePackageSilently(); - else if (d->m_startupActions & ActionRun) - startInferiorIfNeeded(); - else if (d->m_startupActions & ActionDownload) - copyFileFromRemote(); - else - disconnectTrk(); -} - -void Launcher::handleCpuType(const TrkResult &result) -{ - logMessage("HANDLE CPU TYPE: " + result.toString()); - if(result.errorCode() || result.data.size() < 7) - return; - //---TRK------------------------------------------------------ - // Command: 0x80 Acknowledge - // Error: 0x00 - // [80 03 00 04 00 00 04 00 00 00] - d->m_session.cpuMajor = result.data.at(1); - d->m_session.cpuMinor = result.data.at(2); - d->m_session.bigEndian = result.data.at(3); - d->m_session.defaultTypeSize = result.data.at(4); - d->m_session.fpTypeSize = result.data.at(5); - d->m_session.extended1TypeSize = result.data.at(6); - //d->m_session.extended2TypeSize = result.data[6]; -} - -void Launcher::handleCreateProcess(const TrkResult &result) -{ - if (result.errorCode()) { - emit canNotRun(result.errorString()); - disconnectTrk(); - return; - } - // 40 00 00] - //logMessage(" RESULT: " + result.toString()); - // [80 08 00 00 00 01 B5 00 00 01 B6 78 67 40 00 00 40 00 00] - const char *data = result.data.data(); - d->m_session.pid = extractInt(data + 1); - d->m_session.tid = extractInt(data + 5); - d->m_session.codeseg = extractInt(data + 9); - d->m_session.dataseg = extractInt(data + 13); - if (d->m_verbose) { - const QString msg = QString::fromLatin1("Process id: %1 Thread id: %2 code: 0x%3 data: 0x%4"). - arg(d->m_session.pid).arg(d->m_session.tid).arg(d->m_session.codeseg, 0, 16). - arg(d->m_session.dataseg, 0 ,16); - logMessage(msg); - } - emit applicationRunning(d->m_session.pid); - //create a "library" entry for the executable which launched the process - Library lib; - lib.pid = d->m_session.pid; - lib.codeseg = d->m_session.codeseg; - lib.dataseg = d->m_session.dataseg; - lib.name = d->m_fileName.toUtf8(); - d->m_session.libraries << lib; - emit libraryLoaded(lib); - - QByteArray ba; - appendInt(&ba, d->m_session.pid); - appendInt(&ba, d->m_session.tid); - d->m_device->sendTrkMessage(TrkContinue, TrkCallback(), ba, "CONTINUE"); -} - -void Launcher::handleWaitForFinished(const TrkResult &result) -{ - logMessage(" FINISHED: " + stringFromArray(result.data)); - setState(Disconnected); - handleFinished(); -} - -void Launcher::handleSupportMask(const TrkResult &result) -{ - if (result.errorCode() || result.data.size() < 32) - return; - const char *data = result.data.data() + 1; - - if (d->m_verbose > 1) { - QString str = QLatin1String("SUPPORTED: "); - for (int i = 0; i < 32; ++i) { - for (int j = 0; j < 8; ++j) { - if (data[i] & (1 << j)) { - str.append(QString::number(i * 8 + j, 16)); - str.append(QLatin1Char(' ')); - } - } - } - logMessage(str); - } -} - -void Launcher::cleanUp() -{ - // - //---IDE------------------------------------------------------ - // Command: 0x41 Delete Item - // Sub Cmd: Delete Process - //ProcessID: 0x0000071F (1823) - // [41 24 00 00 00 00 07 1F] - QByteArray ba(2, char(0)); - appendInt(&ba, d->m_session.pid); - d->m_device->sendTrkMessage(TrkDeleteItem, TrkCallback(), ba, "Delete process"); - - //---TRK------------------------------------------------------ - // Command: 0x80 Acknowledge - // Error: 0x00 - // [80 24 00] - - //---IDE------------------------------------------------------ - // Command: 0x1C Clear Break - // [1C 25 00 00 00 0A 78 6A 43 40] - - //---TRK------------------------------------------------------ - // Command: 0xA1 Notify Deleted - // [A1 09 00 00 00 00 00 00 00 00 07 1F] - //---IDE------------------------------------------------------ - // Command: 0x80 Acknowledge - // Error: 0x00 - // [80 09 00] - - //---TRK------------------------------------------------------ - // Command: 0x80 Acknowledge - // Error: 0x00 - // [80 25 00] - - //---IDE------------------------------------------------------ - // Command: 0x1C Clear Break - // [1C 26 00 00 00 0B 78 6A 43 70] - //---TRK------------------------------------------------------ - // Command: 0x80 Acknowledge - // Error: 0x00 - // [80 26 00] - - - //---IDE------------------------------------------------------ - // Command: 0x02 Disconnect - // [02 27] -// sendTrkMessage(0x02, TrkCallback(this, &Launcher::handleDisconnect)); - //---TRK------------------------------------------------------ - // Command: 0x80 Acknowledge - // Error: 0x00 -} - -void Launcher::disconnectTrk() -{ - d->m_device->sendTrkMessage(TrkDisconnect, TrkCallback(this, &Launcher::handleWaitForFinished)); -} - -void Launcher::copyFileToRemote() -{ - emit copyingStarted(); - QByteArray ba; - ba.append(char(10)); //kDSFileOpenWrite | kDSFileOpenBinary - appendString(&ba, d->m_copyState.destinationFileName.toLocal8Bit(), TargetByteOrder, false); - d->m_device->sendTrkMessage(TrkOpenFile, TrkCallback(this, &Launcher::handleFileCreation), ba); -} - -void Launcher::copyFileFromRemote() -{ - emit copyingStarted(); - QByteArray ba; - ba.append(char(9)); //kDSFileOpenRead | kDSFileOpenBinary - appendString(&ba, d->m_downloadState.sourceFileName.toLocal8Bit(), TargetByteOrder, false); - d->m_device->sendTrkMessage(TrkOpenFile, TrkCallback(this, &Launcher::handleFileOpened), ba); -} - -void Launcher::installRemotePackageSilently() -{ - emit installingStarted(); - QByteArray ba; - ba.append('C'); - appendString(&ba, d->m_installFileName.toLocal8Bit(), TargetByteOrder, false); - d->m_device->sendTrkMessage(TrkInstallFile, TrkCallback(this, &Launcher::handleInstallPackageFinished), ba); -} - -void Launcher::handleInstallPackageFinished(const TrkResult &result) -{ - if (result.errorCode()) { - emit canNotInstall(d->m_installFileName, result.errorString()); - disconnectTrk(); - return; - } else { - emit installingFinished(); - } - if (d->m_startupActions & ActionRun) { - startInferiorIfNeeded(); - } else if (d->m_startupActions & ActionDownload) { - copyFileFromRemote(); - } else { - disconnectTrk(); - } -} - -QByteArray Launcher::startProcessMessage(const QString &executable, - const QStringList &arguments) -{ - // It's not started yet - QByteArray ba; - appendShort(&ba, 0, TargetByteOrder); // create new process (kDSOSProcessItem) - ba.append(char(0)); // options - currently unused - // One string consisting of binary terminated by '\0' and arguments terminated by '\0' - QByteArray commandLineBa = executable.toLocal8Bit(); - commandLineBa.append(char(0)); - if (!arguments.isEmpty()) - commandLineBa.append(arguments.join(QString(QLatin1Char(' '))).toLocal8Bit()); - appendString(&ba, commandLineBa, TargetByteOrder, true); - return ba; -} - -QByteArray Launcher::readMemoryMessage(uint pid, uint tid, uint from, uint len) -{ - QByteArray ba; - ba.reserve(11); - ba.append(char(0x8)); // Options, FIXME: why? - appendShort(&ba, len); - appendInt(&ba, from); - appendInt(&ba, pid); - appendInt(&ba, tid); - return ba; -} - -QByteArray Launcher::readRegistersMessage(uint pid, uint tid) -{ - QByteArray ba; - ba.reserve(15); - ba.append(char(0)); // Register set, only 0 supported - appendShort(&ba, 0); //R0 - appendShort(&ba, 16); // last register CPSR - appendInt(&ba, pid); - appendInt(&ba, tid); - return ba; -} - -void Launcher::startInferiorIfNeeded() -{ - emit startingApplication(); - if (d->m_session.pid != 0) { - logMessage("Process already 'started'"); - return; - } - d->m_device->sendTrkMessage(TrkCreateItem, TrkCallback(this, &Launcher::handleCreateProcess), - startProcessMessage(d->m_fileName, d->m_commandLineArgs)); // Create Item -} - -void Launcher::resumeProcess(uint pid, uint tid) -{ - QByteArray ba; - appendInt(&ba, pid, BigEndian); - appendInt(&ba, tid, BigEndian); - d->m_device->sendTrkMessage(TrkContinue, TrkCallback(), ba, "CONTINUE"); -} - -// Acquire a device from SymbianDeviceManager, return 0 if not available. -Launcher *Launcher::acquireFromDeviceManager(const QString &serverName, - QObject *parent, - QString *errorMessage) -{ - SymbianUtils::SymbianDeviceManager *sdm = SymbianUtils::SymbianDeviceManager::instance(); - const QSharedPointer<trk::TrkDevice> device = sdm->acquireDevice(serverName); - if (device.isNull()) { - *errorMessage = tr("Unable to acquire a device for port '%1'. It appears to be in use.").arg(serverName); - return 0; - } - // Wire release signal. - Launcher *rc = new Launcher(trk::Launcher::ActionPingOnly, device, parent); - connect(rc, SIGNAL(deviceDescriptionReceived(QString,QString)), - sdm, SLOT(setAdditionalInformation(QString,QString))); - connect(rc, SIGNAL(destroyed(QString)), sdm, SLOT(releaseDevice(QString))); - return rc; -} - -// Preliminary release of device, disconnecting the signal. -void Launcher::releaseToDeviceManager(Launcher *launcher) -{ - SymbianUtils::SymbianDeviceManager *sdm = SymbianUtils::SymbianDeviceManager::instance(); - // Disentangle launcher and its device, remove connection from destroyed - launcher->setCloseDevice(false); - TrkDevice *device = launcher->trkDevice().data(); - launcher->disconnect(device); - device->disconnect(launcher); - launcher->disconnect(sdm); - sdm->releaseDevice(launcher->trkServerName()); -} - -void Launcher::getRegistersAndCallStack(uint pid, uint tid) -{ - d->m_device->sendTrkMessage(TrkReadRegisters, - TrkCallback(this, &Launcher::handleReadRegisters), - Launcher::readRegistersMessage(pid, tid)); - d->m_crashReportState.fetchingStackPID = pid; - d->m_crashReportState.fetchingStackTID = tid; -} - -void Launcher::handleReadRegisters(const TrkResult &result) -{ - if(result.errorCode() || result.data.size() < (17*4)) { - terminate(); - return; - } - const char* data = result.data.constData() + 1; - d->m_crashReportState.registers.clear(); - d->m_crashReportState.stack.clear(); - for (int i=0;i<17;i++) { - uint r = extractInt(data); - data += 4; - d->m_crashReportState.registers.append(r); - } - d->m_crashReportState.sp = d->m_crashReportState.registers.at(13); - - const ushort len = 1024 - (d->m_crashReportState.sp % 1024); //read to 1k boundary first - const QByteArray ba = Launcher::readMemoryMessage(d->m_crashReportState.fetchingStackPID, - d->m_crashReportState.fetchingStackTID, - d->m_crashReportState.sp, - len); - d->m_device->sendTrkMessage(TrkReadMemory, TrkCallback(this, &Launcher::handleReadStack), ba); - d->m_crashReportState.sp += len; -} - -void Launcher::handleReadStack(const TrkResult &result) -{ - if (result.errorCode()) { - //error implies memory fault when reaching end of stack - emit registersAndCallStackReadComplete(d->m_crashReportState.registers, d->m_crashReportState.stack); - return; - } - - const uint len = extractShort(result.data.constData() + 1); - d->m_crashReportState.stack.append(result.data.mid(3, len)); - - if (d->m_crashReportState.sp - d->m_crashReportState.registers.at(13) > 0x10000) { - //read enough stack, stop here - emit registersAndCallStackReadComplete(d->m_crashReportState.registers, d->m_crashReportState.stack); - return; - } - //read 1k more - const QByteArray ba = Launcher::readMemoryMessage(d->m_crashReportState.fetchingStackPID, - d->m_crashReportState.fetchingStackTID, - d->m_crashReportState.sp, - 1024); - d->m_device->sendTrkMessage(TrkReadMemory, TrkCallback(this, &Launcher::handleReadStack), ba); - d->m_crashReportState.sp += 1024; -} - -} // namespace trk diff --git a/src/runonphone/symbianutils/launcher.h b/src/runonphone/symbianutils/launcher.h deleted file mode 100644 index 75e6feda5..000000000 --- a/src/runonphone/symbianutils/launcher.h +++ /dev/null @@ -1,212 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the tools applications of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef LAUNCHER_H -#define LAUNCHER_H - -#include "trkdevice.h" -#include "trkutils.h" - -#include <QtCore/QObject> -#include <QtCore/QVariant> -#include <QtCore/QSharedPointer> - -namespace trk { - -struct TrkResult; -struct TrkMessage; -struct LauncherPrivate; - -typedef QSharedPointer<TrkDevice> TrkDevicePtr; - -class SYMBIANUTILS_EXPORT Launcher : public QObject -{ - Q_OBJECT - Q_DISABLE_COPY(Launcher) -public: - typedef void (Launcher::*TrkCallBack)(const TrkResult &); - - enum Actions { - ActionPingOnly = 0x0, - ActionCopy = 0x1, - ActionInstall = 0x2, - ActionCopyInstall = ActionCopy | ActionInstall, - ActionRun = 0x4, - ActionDownload = 0x8, - ActionCopyRun = ActionCopy | ActionRun, - ActionInstallRun = ActionInstall | ActionRun, - ActionCopyInstallRun = ActionCopy | ActionInstall | ActionRun - }; - - enum State { Disconnected, Connecting, Connected, - WaitingForTrk, // This occurs only if the initial ping times out after - // a reasonable timeout, indicating that Trk is not - // running. Note that this will never happen with - // Bluetooth as communication immediately starts - // after connecting. - DeviceDescriptionReceived }; - - explicit Launcher(trk::Launcher::Actions startupActions = trk::Launcher::ActionPingOnly, - const TrkDevicePtr &trkDevice = TrkDevicePtr(), - QObject *parent = 0); - ~Launcher(); - - State state() const; - - void addStartupActions(trk::Launcher::Actions startupActions); - void setTrkServerName(const QString &name); - QString trkServerName() const; - void setFileName(const QString &name); - void setCopyFileName(const QString &srcName, const QString &dstName); - void setDownloadFileName(const QString &srcName, const QString &dstName); - void setInstallFileName(const QString &name); - void setCommandLineArgs(const QStringList &args); - bool startServer(QString *errorMessage); - void setVerbose(int v); - void setSerialFrame(bool b); - bool serialFrame() const; - // Close device or leave it open - bool closeDevice() const; - void setCloseDevice(bool c); - - TrkDevicePtr trkDevice() const; - - // becomes valid after successful execution of ActionPingOnly - QString deviceDescription(unsigned verbose = 0u) const; - - // Acquire a device from SymbianDeviceManager, return 0 if not available. - // The device will be released on destruction. - static Launcher *acquireFromDeviceManager(const QString &serverName, - QObject *parent, - QString *errorMessage); - // Preliminary release of device, disconnecting the signal. - static void releaseToDeviceManager(Launcher *l); - - // Create Trk message to start a process. - static QByteArray startProcessMessage(const QString &executable, - const QStringList &arguments); - // Create Trk message to read memory - static QByteArray readMemoryMessage(uint pid, uint tid, uint from, uint len); - static QByteArray readRegistersMessage(uint pid, uint tid); - // Parse a TrkNotifyStopped message - static bool parseNotifyStopped(const QByteArray &a, - uint *pid, uint *tid, uint *address, - QString *why = 0); - // Helper message - static QString msgStopped(uint pid, uint tid, uint address, const QString &why); - -signals: - void deviceDescriptionReceived(const QString &port, const QString &description); - void copyingStarted(); - void canNotConnect(const QString &errorMessage); - void canNotCreateFile(const QString &filename, const QString &errorMessage); - void canNotOpenFile(const QString &filename, const QString &errorMessage); - void canNotOpenLocalFile(const QString &filename, const QString &errorMessage); - void canNotWriteFile(const QString &filename, const QString &errorMessage); - void canNotCloseFile(const QString &filename, const QString &errorMessage); - void installingStarted(); - void canNotInstall(const QString &packageFilename, const QString &errorMessage); - void installingFinished(); - void startingApplication(); - void applicationRunning(uint pid); - void canNotRun(const QString &errorMessage); - void finished(); - void applicationOutputReceived(const QString &output); - void copyProgress(int percent); - void stateChanged(int); - void processStopped(uint pc, uint pid, uint tid, const QString& reason); - void processResumed(uint pid, uint tid); - void libraryLoaded(const trk::Library &lib); - void libraryUnloaded(const trk::Library &lib); - void registersAndCallStackReadComplete(const QList<uint>& registers, const QByteArray& stack); - // Emitted by the destructor, for releasing devices of SymbianDeviceManager by name - void destroyed(const QString &serverName); - -public slots: - void terminate(); - void resumeProcess(uint pid, uint tid); - //can be used to obtain traceback after a breakpoint / exception - void getRegistersAndCallStack(uint pid, uint tid); - -private slots: - void handleResult(const trk::TrkResult &data); - void slotWaitingForTrk(); - -private: - // kill process and breakpoints - void cleanUp(); - void disconnectTrk(); - - void handleRemoteProcessKilled(const TrkResult &result); - void handleConnect(const TrkResult &result); - void handleFileCreation(const TrkResult &result); - void handleFileOpened(const TrkResult &result); - void handleCopy(const TrkResult &result); - void handleRead(const TrkResult &result); - void continueCopying(uint lastCopiedBlockSize = 0); - void continueReading(); - void closeRemoteFile(bool failed = false); - void handleFileCopied(const TrkResult &result); - void handleInstallPackageFinished(const TrkResult &result); - void handleCpuType(const TrkResult &result); - void handleCreateProcess(const TrkResult &result); - void handleWaitForFinished(const TrkResult &result); - void handleStop(const TrkResult &result); - void handleSupportMask(const TrkResult &result); - void handleTrkVersion(const TrkResult &result); - void handleReadRegisters(const TrkResult &result); - void handleReadStack(const TrkResult &result); - - void copyFileToRemote(); - void copyFileFromRemote(); - void installRemotePackageSilently(); - void startInferiorIfNeeded(); - void handleFinished(); - - void logMessage(const QString &msg); - void setState(State s); - - LauncherPrivate *d; -}; - -} // namespace Trk - -#endif // LAUNCHER_H diff --git a/src/runonphone/symbianutils/symbiandevicemanager.cpp b/src/runonphone/symbianutils/symbiandevicemanager.cpp deleted file mode 100644 index eee25bef4..000000000 --- a/src/runonphone/symbianutils/symbiandevicemanager.cpp +++ /dev/null @@ -1,489 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the tools applications of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "symbiandevicemanager.h" -#include "trkdevice.h" - -#include <QtCore/QSettings> -#include <QtCore/QStringList> -#include <QtCore/QFileInfo> -#include <QtCore/QtDebug> -#include <QtCore/QTextStream> -#include <QtCore/QSharedData> -#include <QtCore/QScopedPointer> -#include <QtCore/QSignalMapper> - -namespace SymbianUtils { - -enum { debug = 0 }; - -static const char REGKEY_CURRENT_CONTROL_SET[] = "HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet"; -static const char USBSER[] = "Services/usbser/Enum"; - -const char *SymbianDeviceManager::linuxBlueToothDeviceRootC = "/dev/rfcomm"; - -// ------------- SymbianDevice -class SymbianDeviceData : public QSharedData { -public: - SymbianDeviceData(); - ~SymbianDeviceData(); - - inline bool isOpen() const { return !device.isNull() && device->isOpen(); } - void forcedClose(); - - QString portName; - QString friendlyName; - QString deviceDesc; - QString manufacturer; - QString additionalInformation; - - DeviceCommunicationType type; - QSharedPointer<trk::TrkDevice> device; - bool deviceAcquired; -}; - -SymbianDeviceData::SymbianDeviceData() : - type(SerialPortCommunication), - deviceAcquired(false) -{ -} - -SymbianDeviceData::~SymbianDeviceData() -{ - forcedClose(); -} - -void SymbianDeviceData::forcedClose() -{ - // Close the device when unplugging. Should devices be in 'acquired' state, - // their owners should hit on write failures. - // Apart from the <shared item> destructor, also called by the devicemanager - // to ensure it also happens if other shared instances are still around. - if (isOpen()) { - if (deviceAcquired) - qWarning("Device on '%s' unplugged while an operation is in progress.", - qPrintable(portName)); - device->close(); - } -} - -SymbianDevice::SymbianDevice(SymbianDeviceData *data) : - m_data(data) -{ -} - -SymbianDevice::SymbianDevice() : - m_data(new SymbianDeviceData) -{ -} -SymbianDevice::SymbianDevice(const SymbianDevice &rhs) : - m_data(rhs.m_data) -{ -} - -SymbianDevice &SymbianDevice::operator=(const SymbianDevice &rhs) -{ - if (this != &rhs) - m_data = rhs.m_data; - return *this; -} - -SymbianDevice::~SymbianDevice() -{ -} - -void SymbianDevice::forcedClose() -{ - m_data->forcedClose(); -} - -QString SymbianDevice::portName() const -{ - return m_data->portName; -} - -QString SymbianDevice::friendlyName() const -{ - return m_data->friendlyName; -} - -QString SymbianDevice::additionalInformation() const -{ - return m_data->additionalInformation; -} - -void SymbianDevice::setAdditionalInformation(const QString &a) -{ - m_data->additionalInformation = a; -} - -SymbianDevice::TrkDevicePtr SymbianDevice::acquireDevice() -{ - if (debug) - qDebug() << "SymbianDevice::acquireDevice" << m_data->portName - << "acquired: " << m_data->deviceAcquired << " open: " << isOpen(); - if (isNull() || m_data->deviceAcquired) - return TrkDevicePtr(); - if (m_data->device.isNull()) { - m_data->device = TrkDevicePtr(new trk::TrkDevice); - m_data->device->setPort(m_data->portName); - m_data->device->setSerialFrame(m_data->type == SerialPortCommunication); - } - m_data->deviceAcquired = true; - return m_data->device; -} - -void SymbianDevice::releaseDevice(TrkDevicePtr *ptr /* = 0 */) -{ - if (debug) - qDebug() << "SymbianDevice::releaseDevice" << m_data->portName - << " open: " << isOpen(); - if (m_data->deviceAcquired) { - if (m_data->device->isOpen()) - m_data->device->clearWriteQueue(); - // Release if a valid pointer was passed in. - if (ptr && !ptr->isNull()) { - ptr->data()->disconnect(); - *ptr = TrkDevicePtr(); - } - m_data->deviceAcquired = false; - } else { - qWarning("Internal error: Attempt to release device that is not acquired."); - } -} - -QString SymbianDevice::deviceDesc() const -{ - return m_data->deviceDesc; -} - -QString SymbianDevice::manufacturer() const -{ - return m_data->manufacturer; -} - -DeviceCommunicationType SymbianDevice::type() const -{ - return m_data->type; -} - -bool SymbianDevice::isNull() const -{ - return m_data->portName.isEmpty(); -} - -bool SymbianDevice::isOpen() const -{ - return m_data->isOpen(); -} - -QString SymbianDevice::toString() const -{ - QString rc; - QTextStream str(&rc); - format(str); - return rc; -} - -void SymbianDevice::format(QTextStream &str) const -{ - str << (m_data->type == BlueToothCommunication ? "Bluetooth: " : "Serial: ") - << m_data->portName; - if (!m_data->friendlyName.isEmpty()) { - str << " (" << m_data->friendlyName; - if (!m_data->deviceDesc.isEmpty()) - str << " / " << m_data->deviceDesc; - str << ')'; - } - if (!m_data->manufacturer.isEmpty()) - str << " [" << m_data->manufacturer << ']'; -} - -// Compare by port and friendly name -int SymbianDevice::compare(const SymbianDevice &rhs) const -{ - if (const int prc = m_data->portName.compare(rhs.m_data->portName)) - return prc; - if (const int frc = m_data->friendlyName.compare(rhs.m_data->friendlyName)) - return frc; - return 0; -} - -SYMBIANUTILS_EXPORT QDebug operator<<(QDebug d, const SymbianDevice &cd) -{ - d.nospace() << cd.toString(); - return d; -} - -// ------------- SymbianDeviceManagerPrivate -struct SymbianDeviceManagerPrivate { - SymbianDeviceManagerPrivate() : m_initialized(false), m_destroyReleaseMapper(0) {} - - bool m_initialized; - SymbianDeviceManager::SymbianDeviceList m_devices; - QSignalMapper *m_destroyReleaseMapper; -}; - -SymbianDeviceManager::SymbianDeviceManager(QObject *parent) : - QObject(parent), - d(new SymbianDeviceManagerPrivate) -{ -} - -SymbianDeviceManager::~SymbianDeviceManager() -{ - delete d; -} - -SymbianDeviceManager::SymbianDeviceList SymbianDeviceManager::devices() const -{ - ensureInitialized(); - return d->m_devices; -} - -QString SymbianDeviceManager::toString() const -{ - QString rc; - QTextStream str(&rc); - str << d->m_devices.size() << " devices:\n"; - const int count = d->m_devices.size(); - for (int i = 0; i < count; i++) { - str << '#' << i << ' '; - d->m_devices.at(i).format(str); - str << '\n'; - } - return rc; -} - -int SymbianDeviceManager::findByPortName(const QString &p) const -{ - ensureInitialized(); - const int count = d->m_devices.size(); - for (int i = 0; i < count; i++) - if (d->m_devices.at(i).portName() == p) - return i; - return -1; -} - -QString SymbianDeviceManager::friendlyNameForPort(const QString &port) const -{ - const int idx = findByPortName(port); - return idx == -1 ? QString() : d->m_devices.at(idx).friendlyName(); -} - -SymbianDeviceManager::TrkDevicePtr - SymbianDeviceManager::acquireDevice(const QString &port) -{ - ensureInitialized(); - const int idx = findByPortName(port); - if (idx == -1) { - qWarning("Attempt to acquire device '%s' that does not exist.", qPrintable(port)); - if (debug) - qDebug() << *this; - return TrkDevicePtr(); - } - const TrkDevicePtr rc = d->m_devices[idx].acquireDevice(); - if (debug) - qDebug() << "SymbianDeviceManager::acquireDevice" << port << " returns " << !rc.isNull(); - return rc; -} - -void SymbianDeviceManager::update() -{ - update(true); -} - -void SymbianDeviceManager::releaseDevice(const QString &port) -{ - const int idx = findByPortName(port); - if (debug) - qDebug() << "SymbianDeviceManager::releaseDevice" << port << idx << sender(); - if (idx != -1) { - d->m_devices[idx].releaseDevice(); - } else { - qWarning("Attempt to release non-existing device %s.", qPrintable(port)); - } -} - -void SymbianDeviceManager::setAdditionalInformation(const QString &port, const QString &ai) -{ - const int idx = findByPortName(port); - if (idx != -1) - d->m_devices[idx].setAdditionalInformation(ai); -} - -void SymbianDeviceManager::ensureInitialized() const -{ - if (!d->m_initialized) // Flag is set in update() - const_cast<SymbianDeviceManager*>(this)->update(false); -} - -void SymbianDeviceManager::update(bool emitSignals) -{ - static int n = 0; - typedef SymbianDeviceList::iterator SymbianDeviceListIterator; - - if (debug) - qDebug(">SerialDeviceLister::update(#%d, signals=%d)\n%s", n++, int(emitSignals), - qPrintable(toString())); - - d->m_initialized = true; - // Get ordered new list - SymbianDeviceList newDevices = serialPorts() + blueToothDevices(); - if (newDevices.size() > 1) - qStableSort(newDevices.begin(), newDevices.end()); - if (d->m_devices == newDevices) { // Happy, nothing changed. - if (debug) - qDebug("<SerialDeviceLister::update: unchanged\n"); - return; - } - // Merge the lists and emit the respective added/removed signals, assuming - // no one can plug a different device on the same port at the speed of lightning - if (!d->m_devices.isEmpty()) { - // Find deleted devices - for (SymbianDeviceListIterator oldIt = d->m_devices.begin(); oldIt != d->m_devices.end(); ) { - if (newDevices.contains(*oldIt)) { - ++oldIt; - } else { - SymbianDevice toBeDeleted = *oldIt; - toBeDeleted.forcedClose(); - oldIt = d->m_devices.erase(oldIt); - if (emitSignals) - emit deviceRemoved(toBeDeleted); - } - } - } - if (!newDevices.isEmpty()) { - // Find new devices and insert in order - foreach(const SymbianDevice &newDevice, newDevices) { - if (!d->m_devices.contains(newDevice)) { - d->m_devices.append(newDevice); - if (emitSignals) - emit deviceAdded(newDevice); - } - } - if (d->m_devices.size() > 1) - qStableSort(d->m_devices.begin(), d->m_devices.end()); - } - if (emitSignals) - emit updated(); - - if (debug) - qDebug("<SerialDeviceLister::update\n%s\n", qPrintable(toString())); -} - -SymbianDeviceManager::SymbianDeviceList SymbianDeviceManager::serialPorts() const -{ - SymbianDeviceList rc; -#ifdef Q_OS_WIN - const QSettings registry(REGKEY_CURRENT_CONTROL_SET, QSettings::NativeFormat); - const QString usbSerialRootKey = QLatin1String(USBSER) + QLatin1Char('/'); - const int count = registry.value(usbSerialRootKey + QLatin1String("Count")).toInt(); - for (int i = 0; i < count; ++i) { - QString driver = registry.value(usbSerialRootKey + QString::number(i)).toString(); - if (driver.contains(QLatin1String("JAVACOMM"))) { - driver.replace(QLatin1Char('\\'), QLatin1Char('/')); - const QString driverRootKey = QLatin1String("Enum/") + driver + QLatin1Char('/'); - if (debug > 1) - qDebug() << "SerialDeviceLister::serialPorts(): Checking " << i << count - << REGKEY_CURRENT_CONTROL_SET << usbSerialRootKey << driverRootKey; - QScopedPointer<SymbianDeviceData> device(new SymbianDeviceData); - device->type = SerialPortCommunication; - device->friendlyName = registry.value(driverRootKey + QLatin1String("FriendlyName")).toString(); - device->portName = registry.value(driverRootKey + QLatin1String("Device Parameters/PortName")).toString(); - device->deviceDesc = registry.value(driverRootKey + QLatin1String("DeviceDesc")).toString(); - device->manufacturer = registry.value(driverRootKey + QLatin1String("Mfg")).toString(); - rc.append(SymbianDevice(device.take())); - } - } -#endif - return rc; -} - -SymbianDeviceManager::SymbianDeviceList SymbianDeviceManager::blueToothDevices() const -{ - SymbianDeviceList rc; -#if defined(Q_OS_UNIX) && !defined(Q_OS_MAC) - // Bluetooth devices are created on connection. List the existing ones - // or at least the first one. - const QString prefix = QLatin1String(linuxBlueToothDeviceRootC); - const QString blueToothfriendlyFormat = QLatin1String("Bluetooth device (%1)"); - for (int d = 0; d < 4; d++) { - QScopedPointer<SymbianDeviceData> device(new SymbianDeviceData); - device->type = BlueToothCommunication; - device->portName = prefix + QString::number(d); - if (d == 0 || QFileInfo(device->portName).exists()) { - device->friendlyName = blueToothfriendlyFormat.arg(device->portName); - rc.push_back(SymbianDevice(device.take())); - } - } - // New kernel versions support /dev/ttyUSB0, /dev/ttyUSB1. Trk responds - // on the latter (usually), try first. - static const char *usbTtyDevices[] = { "/dev/ttyUSB1", "/dev/ttyUSB0" }; - const int usbTtyCount = sizeof(usbTtyDevices)/sizeof(const char *); - for (int d = 0; d < usbTtyCount; d++) { - const QString ttyUSBDevice = QLatin1String(usbTtyDevices[d]); - if (QFileInfo(ttyUSBDevice).exists()) { - SymbianDeviceData *device = new SymbianDeviceData; - device->type = SerialPortCommunication; - device->portName = ttyUSBDevice; - device->friendlyName = QString::fromLatin1("USB/Serial device (%1)").arg(device->portName); - rc.push_back(SymbianDevice(device)); - } - } -#endif - return rc; -} - -Q_GLOBAL_STATIC(SymbianDeviceManager, symbianDeviceManager) - -SymbianDeviceManager *SymbianDeviceManager::instance() -{ - return symbianDeviceManager(); -} - -SYMBIANUTILS_EXPORT QDebug operator<<(QDebug d, const SymbianDeviceManager &sdm) -{ - d.nospace() << sdm.toString(); - return d; -} - -} // namespace SymbianUtilsInternal diff --git a/src/runonphone/symbianutils/symbiandevicemanager.h b/src/runonphone/symbianutils/symbiandevicemanager.h deleted file mode 100644 index b79297f9b..000000000 --- a/src/runonphone/symbianutils/symbiandevicemanager.h +++ /dev/null @@ -1,178 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the tools applications of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef SYMBIANDEVICEMANAGER_H -#define SYMBIANDEVICEMANAGER_H - -#include "symbianutils_global.h" - -#include <QtCore/QObject> -#include <QtCore/QExplicitlySharedDataPointer> -#include <QtCore/QSharedPointer> - -QT_BEGIN_NAMESPACE -class QDebug; -class QTextStream; -QT_END_NAMESPACE - -namespace trk { - class TrkDevice; -} - -namespace SymbianUtils { - -struct SymbianDeviceManagerPrivate; -class SymbianDeviceData; - -enum DeviceCommunicationType { - SerialPortCommunication = 0, - BlueToothCommunication = 1 -}; - -// SymbianDevice: Explicitly shared device data and a TrkDevice -// instance that can be acquired (exclusively) for use. -// A device removal from the manager will result in the -// device being closed. -class SYMBIANUTILS_EXPORT SymbianDevice { - explicit SymbianDevice(SymbianDeviceData *data); - friend class SymbianDeviceManager; -public: - typedef QSharedPointer<trk::TrkDevice> TrkDevicePtr; - - SymbianDevice(); - SymbianDevice(const SymbianDevice &rhs); - SymbianDevice &operator=(const SymbianDevice &rhs); - ~SymbianDevice(); - int compare(const SymbianDevice &rhs) const; - - DeviceCommunicationType type() const; - bool isNull() const; - QString portName() const; - QString friendlyName() const; - QString additionalInformation() const; - void setAdditionalInformation(const QString &); - - // Acquire: Mark the device as 'out' and return a shared pointer - // unless it is already in use by another owner. The result should not - // be passed on further. - TrkDevicePtr acquireDevice(); - // Give back a device and mark it as 'free'. - void releaseDevice(TrkDevicePtr *ptr = 0); - - bool isOpen() const; - - // Windows only. - QString deviceDesc() const; - QString manufacturer() const; - - void format(QTextStream &str) const; - QString toString() const; - -private: - void forcedClose(); - - QExplicitlySharedDataPointer<SymbianDeviceData> m_data; -}; - -SYMBIANUTILS_EXPORT QDebug operator<<(QDebug d, const SymbianDevice &); - -inline bool operator==(const SymbianDevice &d1, const SymbianDevice &d2) - { return d1.compare(d2) == 0; } -inline bool operator!=(const SymbianDevice &d1, const SymbianDevice &d2) - { return d1.compare(d2) != 0; } -inline bool operator<(const SymbianDevice &d1, const SymbianDevice &d2) - { return d1.compare(d2) < 0; } - -/* SymbianDeviceManager: Singleton that maintains a list of Symbian devices. - * and emits change signals. - * On Windows, the update slot must be connected to a [delayed] signal - * emitted from an event handler listening for WM_DEVICECHANGE. - * Device removal will result in the device being closed. */ -class SYMBIANUTILS_EXPORT SymbianDeviceManager : public QObject -{ - Q_OBJECT -public: - typedef QList<SymbianDevice> SymbianDeviceList; - typedef QSharedPointer<trk::TrkDevice> TrkDevicePtr; - - static const char *linuxBlueToothDeviceRootC; - - // Do not use this constructor, it is just public for Q_GLOBAL_STATIC - explicit SymbianDeviceManager(QObject *parent = 0); - virtual ~SymbianDeviceManager(); - - // Singleton access. - static SymbianDeviceManager *instance(); - - SymbianDeviceList devices() const; - QString toString() const; - - // Acquire a device for use. See releaseDevice(). - TrkDevicePtr acquireDevice(const QString &port); - - int findByPortName(const QString &p) const; - QString friendlyNameForPort(const QString &port) const; - -public slots: - void update(); - // Relase a device, make it available for further use. - void releaseDevice(const QString &port); - void setAdditionalInformation(const QString &port, const QString &ai); - -signals: - void deviceRemoved(const SymbianUtils::SymbianDevice &d); - void deviceAdded(const SymbianUtils::SymbianDevice &d); - void updated(); - -private: - void ensureInitialized() const; - void update(bool emitSignals); - SymbianDeviceList serialPorts() const; - SymbianDeviceList blueToothDevices() const; - - SymbianDeviceManagerPrivate *d; -}; - -SYMBIANUTILS_EXPORT QDebug operator<<(QDebug d, const SymbianDeviceManager &); - -} // namespace SymbianUtils - -#endif // SYMBIANDEVICEMANAGER_H diff --git a/src/runonphone/symbianutils/symbianutils.pri b/src/runonphone/symbianutils/symbianutils.pri deleted file mode 100644 index f07e494ed..000000000 --- a/src/runonphone/symbianutils/symbianutils.pri +++ /dev/null @@ -1,35 +0,0 @@ -INCLUDEPATH *= $$PWD - -QT += network - -# Input -HEADERS += $$PWD/symbianutils_global.h \ - $$PWD/callback.h \ - $$PWD/trkutils.h \ - $$PWD/trkutils_p.h \ - $$PWD/trkdevice.h \ - $$PWD/launcher.h \ - $$PWD/bluetoothlistener.h \ - $$PWD/communicationstarter.h \ - $$PWD/symbiandevicemanager.h \ - $$PWD/tcftrkdevice.h \ - $$PWD/tcftrkmessage.h \ - $$PWD/json.h - -SOURCES += $$PWD/trkutils.cpp \ - $$PWD/trkdevice.cpp \ - $$PWD/launcher.cpp \ - $$PWD/bluetoothlistener.cpp \ - $$PWD/communicationstarter.cpp \ - $$PWD/symbiandevicemanager.cpp \ - $$PWD/tcftrkdevice.cpp \ - $$PWD/tcftrkmessage.cpp \ - $$PWD/json.cpp - -# Tests/trklauncher is a console application -contains(QT, gui) { - HEADERS += $$PWD/bluetoothlistener_gui.h - SOURCES += $$PWD/bluetoothlistener_gui.cpp -} else { - message(Trk: Console ...) -} diff --git a/src/runonphone/symbianutils/symbianutils_global.h b/src/runonphone/symbianutils/symbianutils_global.h deleted file mode 100644 index 3ebb19904..000000000 --- a/src/runonphone/symbianutils/symbianutils_global.h +++ /dev/null @@ -1,55 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the tools applications of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef SYMBIANUTILS_GLOBAL_H -#define SYMBIANUTILS_GLOBAL_H - -#include <QtCore/qglobal.h> - -#if defined(SYMBIANUTILS_BUILD_LIB) -# define SYMBIANUTILS_EXPORT Q_DECL_EXPORT -#elif defined(SYMBIANUTILS_BUILD_STATIC_LIB) || defined(SYMBIANUTILS_INCLUDE_PRI) -# define SYMBIANUTILS_EXPORT -#else -# define SYMBIANUTILS_EXPORT Q_DECL_IMPORT -#endif - -#endif // SYMBIANUTILS_GLOBAL_H diff --git a/src/runonphone/symbianutils/tcftrkdevice.cpp b/src/runonphone/symbianutils/tcftrkdevice.cpp deleted file mode 100644 index 1acf6a9fe..000000000 --- a/src/runonphone/symbianutils/tcftrkdevice.cpp +++ /dev/null @@ -1,929 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the tools applications of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "tcftrkdevice.h" -#include "json.h" - -#include <QtNetwork/QAbstractSocket> -#include <QtCore/QDebug> -#include <QtCore/QVector> -#include <QtCore/QQueue> -#include <QtCore/QTextStream> -#include <QtCore/QDateTime> -#include <QtCore/QFileInfo> - -enum { debug = 0 }; - -static const char messageTerminatorC[] = "\003\001"; - -namespace tcftrk { -// ------------- TcfTrkCommandError - -TcfTrkCommandError::TcfTrkCommandError() : timeMS(0), code(0), alternativeCode(0) -{ -} - -void TcfTrkCommandError::clear() -{ - timeMS = 0; - code = alternativeCode = 0; - format.clear(); - alternativeOrganization.clear(); -} - -void TcfTrkCommandError::write(QTextStream &str) const -{ - if (timeMS) { - const QDateTime time(QDate(1970, 1, 1)); - str << time.addMSecs(timeMS).toString(Qt::ISODate) << ": Error code: " << code - << " '" << format << '\''; - if (!alternativeOrganization.isEmpty()) - str << " ('" << alternativeOrganization << "', code: " << alternativeCode << ')'; - } else{ - str << "<No error>"; - } -} - -QString TcfTrkCommandError::toString() const -{ - QString rc; - QTextStream str(&rc); - write(str); - return rc; -} - -/* {"Time":1277459762255,"Code":1,"AltCode":-6,"AltOrg":"POSIX","Format":"Unknown error: -6"} */ -bool TcfTrkCommandError::parse(const QVector<JsonValue> &values) -{ - // Parse an arbitrary hash (that could as well be a command response) - // and check for error elements. - unsigned errorKeyCount = 0; - clear(); - do { - if (values.isEmpty() || values.front().type() != JsonValue::Object) - break; - foreach (const JsonValue &c, values.front().children()) { - if (c.name() == "Time") { - timeMS = c.data().toULongLong(); - errorKeyCount++; - } else if (c.name() == "Code") { - code = c.data().toInt(); - errorKeyCount++; - } else if (c.name() == "Format") { - format = c.data(); - errorKeyCount++; - } else if (c.name() == "AltCode") { - alternativeCode = c.data().toInt(); - errorKeyCount++; - } else if (c.name() == "AltOrg") { - alternativeOrganization = c.data(); - errorKeyCount++; - } - } - } while (false); - const bool errorFound = errorKeyCount >= 2u; // Should be at least 'Time', 'Code'. - if (!errorFound) - clear(); - if (debug) { - qDebug() << "TcfTrkCommandError::parse: Found error: " << errorFound; - if (!values.isEmpty()) - qDebug() << values.front().toString(); - } - return errorFound; -} - -// ------------ TcfTrkCommandResult - -TcfTrkCommandResult::TcfTrkCommandResult(Type t) : - type(t), service(LocatorService) -{ -} - -TcfTrkCommandResult::TcfTrkCommandResult(char typeChar, Services s, - const QByteArray &r, - const QVector<JsonValue> &v, - const QVariant &ck) : - type(FailReply), service(s), request(r), values(v), cookie(ck) -{ - switch (typeChar) { - case 'N': - type = FailReply; - break; - case 'P': - type = ProgressReply; - break; - case 'R': - type = commandError.parse(values) ? CommandErrorReply : SuccessReply; - break; - default: - qWarning("Unknown TCF reply type '%c'", typeChar); - } -} - -QString TcfTrkCommandResult::errorString() const -{ - QString rc; - QTextStream str(&rc); - - switch (type) { - case SuccessReply: - case ProgressReply: - str << "<No error>"; - return rc; - case FailReply: - str << "NAK"; - case CommandErrorReply: - commandError.write(str); - break; - } - // Append the failed command for reference - str << " (Command was: '"; - QByteArray printableRequest = request; - printableRequest.replace('\0', '|'); - str << printableRequest << "')"; - return rc; -} - -QString TcfTrkCommandResult::toString() const -{ - QString rc; - QTextStream str(&rc); - str << "Command answer "; - switch (type) { - case SuccessReply: - str << "[success]"; - break; - case CommandErrorReply: - str << "[command error]"; - break; - case FailReply: - str << "[fail (NAK)]"; - break; - case ProgressReply: - str << "[progress]"; - break; - } - str << ", " << values.size() << " values(s) to request: '"; - QByteArray printableRequest = request; - printableRequest.replace('\0', '|'); - str << printableRequest << "' "; - if (cookie.isValid()) - str << " cookie: " << cookie.toString(); - str << '\n'; - for (int i = 0, count = values.size(); i < count; i++) - str << '#' << i << ' ' << values.at(i).toString() << '\n'; - if (type == CommandErrorReply) - str << "Error: " << errorString(); - return rc; -} - -struct TcfTrkSendQueueEntry -{ - typedef TcfTrkDevice::MessageType MessageType; - - explicit TcfTrkSendQueueEntry(MessageType mt, - int tok, - Services s, - const QByteArray &d, - const TcfTrkCallback &cb= TcfTrkCallback(), - const QVariant &ck = QVariant()) : - messageType(mt), service(s), data(d), token(tok), cookie(ck), callback(cb) {} - - MessageType messageType; - Services service; - QByteArray data; - int token; - QVariant cookie; - TcfTrkCallback callback; -}; - -struct TcfTrkDevicePrivate { - typedef TcfTrkDevice::IODevicePtr IODevicePtr; - typedef QHash<int, TcfTrkSendQueueEntry> TokenWrittenMessageMap; - - TcfTrkDevicePrivate(); - - const QByteArray m_messageTerminator; - - IODevicePtr m_device; - unsigned m_verbose; - QByteArray m_readBuffer; - int m_token; - QQueue<TcfTrkSendQueueEntry> m_sendQueue; - TokenWrittenMessageMap m_writtenMessages; - QVector<QByteArray> m_registerNames; -}; - -TcfTrkDevicePrivate::TcfTrkDevicePrivate() : - m_messageTerminator(messageTerminatorC), - m_verbose(0), m_token(0) -{ -} - -TcfTrkDevice::TcfTrkDevice(QObject *parent) : - QObject(parent), d(new TcfTrkDevicePrivate) -{ -} - -TcfTrkDevice::~TcfTrkDevice() -{ - delete d; -} - -QVector<QByteArray> TcfTrkDevice::registerNames() const -{ - return d->m_registerNames; -} - -void TcfTrkDevice::setRegisterNames(const QVector<QByteArray>& n) -{ - d->m_registerNames = n; - if (d->m_verbose) { - QString msg; - QTextStream str(&msg); - const int count = n.size(); - str << "Registers (" << count << "): "; - for (int i = 0; i < count; i++) - str << '#' << i << '=' << n.at(i) << ' '; - emitLogMessage(msg); - } -} - -TcfTrkDevice::IODevicePtr TcfTrkDevice::device() const -{ - return d->m_device; -} - -TcfTrkDevice::IODevicePtr TcfTrkDevice::takeDevice() -{ - const IODevicePtr old = d->m_device; - if (!old.isNull()) { - old.data()->disconnect(this); - d->m_device = IODevicePtr(); - } - d->m_readBuffer.clear(); - d->m_token = 0; - d->m_sendQueue.clear(); - return old; -} - -void TcfTrkDevice::setDevice(const IODevicePtr &dp) -{ - if (dp.data() == d->m_device.data()) - return; - if (dp.isNull()) { - emitLogMessage(QLatin1String("Internal error: Attempt to set NULL device.")); - return; - } - takeDevice(); - d->m_device = dp; - connect(dp.data(), SIGNAL(readyRead()), this, SLOT(slotDeviceReadyRead())); - if (QAbstractSocket *s = qobject_cast<QAbstractSocket *>(dp.data())) { - connect(s, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(slotDeviceError())); - connect(s, SIGNAL(stateChanged(QAbstractSocket::SocketState)), this, SLOT(slotDeviceSocketStateChanged())); - } -} - -void TcfTrkDevice::slotDeviceError() -{ - const QString message = d->m_device->errorString(); - emitLogMessage(message); - emit error(message); -} - -void TcfTrkDevice::slotDeviceSocketStateChanged() -{ - if (const QAbstractSocket *s = qobject_cast<const QAbstractSocket *>(d->m_device.data())) { - const QAbstractSocket::SocketState st = s->state(); - switch (st) { - case QAbstractSocket::UnconnectedState: - emitLogMessage(QLatin1String("Unconnected")); - break; - case QAbstractSocket::HostLookupState: - emitLogMessage(QLatin1String("HostLookupState")); - break; - case QAbstractSocket::ConnectingState: - emitLogMessage(QLatin1String("Connecting")); - break; - case QAbstractSocket::ConnectedState: - emitLogMessage(QLatin1String("Connected")); - break; - case QAbstractSocket::ClosingState: - emitLogMessage(QLatin1String("Closing")); - break; - default: - emitLogMessage(QString::fromLatin1("State %1").arg(st)); - break; - } - } -} - -static inline QString debugMessage(QByteArray message, const char *prefix = 0) -{ - message.replace('\0', '|'); - const QString messageS = QString::fromLatin1(message); - return prefix ? - (QLatin1String(prefix) + messageS) : messageS; -} - -void TcfTrkDevice::slotDeviceReadyRead() -{ - d->m_readBuffer += d->m_device->readAll(); - // Take complete message off front of readbuffer. - do { - const int messageEndPos = d->m_readBuffer.indexOf(d->m_messageTerminator); - if (messageEndPos == -1) - break; - const QByteArray message = d->m_readBuffer.left(messageEndPos); - if (debug) - qDebug("Read:\n%s", qPrintable(formatData(message))); - if (const int errorCode = parseMessage(message)) { - emitLogMessage(QString::fromLatin1("Parse error %1 for: %2").arg(errorCode).arg(debugMessage(message))); - } - d->m_readBuffer.remove(0, messageEndPos + d->m_messageTerminator.size()); - } while (!d->m_readBuffer.isEmpty()); - checkSendQueue(); // Send off further message -} - -// Split \0-terminated message into tokens, skipping the initial type character -static inline QVector<QByteArray> splitMessage(const QByteArray &message) -{ - QVector<QByteArray> tokens; - tokens.reserve(7); - const int messageSize = message.size(); - for (int pos = 2; pos < messageSize; ) { - const int nextPos = message.indexOf('\0', pos); - if (nextPos == -1) - break; - tokens.push_back(message.mid(pos, nextPos - pos)); - pos = nextPos + 1; - } - return tokens; -} - -int TcfTrkDevice::parseMessage(const QByteArray &message) -{ - if (d->m_verbose) - emitLogMessage(debugMessage(message, "TCF ->")); - // Special JSON parse error message or protocol format error. - // The port is usually closed after receiving it. - // "\3\2{"Time":1276096098255,"Code":3,"Format": "Protocol format error"}" - if (message.startsWith("\003\002")) { - QByteArray text = message.mid(2); - const QString errorMessage = QString::fromLatin1("Parse error received: %1").arg(QString::fromLatin1(text)); - emit error(errorMessage); - return 0; - } - if (message.size() < 4 || message.at(1) != '\0') - return 1; - // Split into tokens - const char type = message.at(0); - const QVector<QByteArray> tokens = splitMessage(message); - switch (type) { - case 'E': - return parseTcfEvent(tokens); - case 'R': // Command replies - case 'N': - case 'P': - return parseTcfCommandReply(type, tokens); - default: - emitLogMessage(QString::fromLatin1("Unhandled message type: %1").arg(debugMessage(message))); - return 756; - } - return 0; -} - -int TcfTrkDevice::parseTcfCommandReply(char type, const QVector<QByteArray> &tokens) -{ - typedef TcfTrkDevicePrivate::TokenWrittenMessageMap::iterator TokenWrittenMessageMapIterator; - // Find the corresponding entry in the written messages hash. - const int tokenCount = tokens.size(); - if (tokenCount < 1) - return 234; - bool tokenOk; - const int token = tokens.at(0).toInt(&tokenOk); - if (!tokenOk) - return 235; - const TokenWrittenMessageMapIterator it = d->m_writtenMessages.find(token); - if (it == d->m_writtenMessages.end()) { - qWarning("TcfTrkDevice: Internal error: token %d not found for '%s'", - token, qPrintable(joinByteArrays(tokens))); - return 236; - } - // No callback: remove entry from map, happy - if (!it.value().callback) { - d->m_writtenMessages.erase(it); - return 0; - } - // Parse values into JSON - QVector<JsonValue> values; - values.reserve(tokenCount); - for (int i = 1; i < tokenCount; i++) { - if (!tokens.at(i).isEmpty()) { // Strange: Empty tokens occur. - const JsonValue value(tokens.at(i)); - if (value.isValid()) { - values.push_back(value); - } else { - qWarning("JSON parse error for reply to command token %d: #%d '%s'", - token, i, tokens.at(i).constData()); - d->m_writtenMessages.erase(it); - return -1; - } - } - } - - // Construct result and invoke callback, remove entry from map. - TcfTrkCallback callback = it.value().callback; - TcfTrkCommandResult result(type, it.value().service, it.value().data, - values, it.value().cookie); - d->m_writtenMessages.erase(it); - callback(result); - return 0; -} - -static const char locatorAnswerC[] = "E\0Locator\0Hello\0[\"Locator\"]"; - -int TcfTrkDevice::parseTcfEvent(const QVector<QByteArray> &tokens) -{ - // Event: Ignore the periodical heartbeat event, answer 'Hello', - // emit signal for the rest - if (tokens.size() < 3) - return 433; - const Services service = serviceFromName(tokens.at(0).constData()); - if (service == LocatorService && tokens.at(1) == "peerHeartBeat") - return 0; - QVector<JsonValue> values; - for (int i = 2; i < tokens.size(); i++) { - const JsonValue value(tokens.at(i)); - if (!value.isValid()) - return 434; - values.push_back(value); - } - // Parse known events, emit signals - QScopedPointer<TcfTrkEvent> knownEvent(TcfTrkEvent::parseEvent(service, tokens.at(1), values)); - if (!knownEvent.isNull()) { - // Answer hello event. - if (knownEvent->type() == TcfTrkEvent::LocatorHello) - writeMessage(QByteArray(locatorAnswerC, sizeof(locatorAnswerC))); - emit tcfEvent(*knownEvent); - } - emit genericTcfEvent(service, tokens.at(1), values); - - if (debug || d->m_verbose) { - QString msg; - QTextStream str(&msg); - if (knownEvent.isNull()) { - str << "Event: " << tokens.at(0) << ' ' << tokens.at(1) << '\n'; - foreach(const JsonValue &val, values) - str << " " << val.toString() << '\n'; - } else { - str << knownEvent->toString(); - } - emitLogMessage(msg); - } - - return 0; -} - -unsigned TcfTrkDevice::verbose() const -{ - return d->m_verbose; -} - -void TcfTrkDevice::setVerbose(unsigned v) -{ - d->m_verbose = v; -} - -void TcfTrkDevice::emitLogMessage(const QString &m) -{ - if (debug) - qWarning("%s", qPrintable(m)); - emit logMessage(m); -} - -bool TcfTrkDevice::checkOpen() -{ - if (d->m_device.isNull()) { - emitLogMessage(QLatin1String("Internal error: No device set on TcfTrkDevice.")); - return false; - } - if (!d->m_device->isOpen()) { - emitLogMessage(QLatin1String("Internal error: Device not open in TcfTrkDevice.")); - return false; - } - return true; -} - -void TcfTrkDevice::sendTcfTrkMessage(MessageType mt, Services service, const char *command, - const char *commandParameters, int commandParametersLength, - const TcfTrkCallback &callBack, - const QVariant &cookie) - -{ - if (!checkOpen()) - return; - // Format the message - const int token = d->m_token++; - QByteArray data; - data.reserve(30 + commandParametersLength); - data.append('C'); - data.append('\0'); - data.append(QByteArray::number(token)); - data.append('\0'); - data.append(serviceName(service)); - data.append('\0'); - data.append(command); - data.append('\0'); - if (commandParametersLength) - data.append(commandParameters, commandParametersLength); - const TcfTrkSendQueueEntry entry(mt, token, service, data, callBack, cookie); - d->m_sendQueue.enqueue(entry); - checkSendQueue(); -} - -void TcfTrkDevice::sendTcfTrkMessage(MessageType mt, Services service, const char *command, - const QByteArray &commandParameters, - const TcfTrkCallback &callBack, - const QVariant &cookie) -{ - sendTcfTrkMessage(mt, service, command, commandParameters.constData(), commandParameters.size(), - callBack, cookie); -} - -// Enclose in message frame and write. -void TcfTrkDevice::writeMessage(QByteArray data) -{ - if (!checkOpen()) - return; - - if (d->m_verbose) - emitLogMessage(debugMessage(data, "TCF <-")); - - // Ensure \0-termination which easily gets lost in QByteArray CT. - if (!data.endsWith('\0')) - data.append('\0'); - data += d->m_messageTerminator; - - if (debug > 1) - qDebug("Writing:\n%s", qPrintable(formatData(data))); - - d->m_device->write(data); - if (QAbstractSocket *as = qobject_cast<QAbstractSocket *>(d->m_device.data())) - as->flush(); -} - -void TcfTrkDevice::checkSendQueue() -{ - // Fire off messages or invoke noops until a message with reply is found - // and an entry to writtenMessages is made. - while (d->m_writtenMessages.empty()) { - if (d->m_sendQueue.isEmpty()) - break; - TcfTrkSendQueueEntry entry = d->m_sendQueue.dequeue(); - switch (entry.messageType) { - case MessageWithReply: - d->m_writtenMessages.insert(entry.token, entry); - writeMessage(entry.data); - break; - case MessageWithoutReply: - writeMessage(entry.data); - break; - case NoopMessage: // Invoke the noop-callback for synchronization - if (entry.callback) { - TcfTrkCommandResult noopResult(TcfTrkCommandResult::SuccessReply); - noopResult.cookie = entry.cookie; - entry.callback(noopResult); - } - break; - } - } -} - -// Fix slashes -static inline QString fixFileName(QString in) -{ - in.replace(QLatin1Char('/'), QLatin1Char('\\')); - return in; -} - -// Start a process (consisting of a non-reply setSettings and start). -void TcfTrkDevice::sendProcessStartCommand(const TcfTrkCallback &callBack, - const QString &binaryIn, - unsigned uid, - QStringList arguments, - QString workingDirectory, - bool debugControl, - const QStringList &additionalLibraries, - const QVariant &cookie) -{ - // Obtain the bin directory, expand by c:/sys/bin if missing - const QChar backSlash('\\'); - int slashPos = binaryIn.lastIndexOf(QLatin1Char('/')); - if (slashPos == -1) - slashPos = binaryIn.lastIndexOf(backSlash); - const QString sysBin = QLatin1String("c:/sys/bin"); - const QString binaryFileName = slashPos == -1 ? binaryIn : binaryIn.mid(slashPos + 1); - const QString binaryDirectory = slashPos == -1 ? sysBin : binaryIn.left(slashPos); - const QString binary = fixFileName(binaryDirectory + QLatin1Char('/') + binaryFileName); - - // Fixup: Does argv[0] convention exist on Symbian? - arguments.push_front(binary); - if (workingDirectory.isEmpty()) - workingDirectory = sysBin; - - // Format settings with empty dummy parameter - QByteArray setData; - JsonInputStream setStr(setData); - setStr << "" << '\0' - << '[' << "exeToLaunch" << ',' << "addExecutables" << ',' << "addLibraries" << ']' - << '\0' << '[' - << binary << ',' - << '{' << binaryFileName << ':' << QString::number(uid, 16) << '}' << ',' - << additionalLibraries - << ']'; - sendTcfTrkMessage(MessageWithoutReply, SettingsService, "set", setData); - - QByteArray startData; - JsonInputStream startStr(startData); - startStr << fixFileName(workingDirectory) - << '\0' << binary << '\0' << arguments << '\0' - << QStringList() << '\0' // Env is an array ["PATH=value"] (non-standard) - << debugControl; - sendTcfTrkMessage(MessageWithReply, ProcessesService, "start", startData, callBack, cookie); -} - -void TcfTrkDevice::sendProcessTerminateCommand(const TcfTrkCallback &callBack, - const QByteArray &id, - const QVariant &cookie) -{ - QByteArray data; - JsonInputStream str(data); - str << id; - sendTcfTrkMessage(MessageWithReply, ProcessesService, "terminate", data, callBack, cookie); -} - -void TcfTrkDevice::sendRunControlTerminateCommand(const TcfTrkCallback &callBack, - const QByteArray &id, - const QVariant &cookie) -{ - QByteArray data; - JsonInputStream str(data); - str << id; - sendTcfTrkMessage(MessageWithReply, RunControlService, "terminate", data, callBack, cookie); -} - -// Non-standard: Remove executable from settings -void TcfTrkDevice::sendSettingsRemoveExecutableCommand(const QString &binaryIn, - unsigned uid, - const QStringList &additionalLibraries, - const QVariant &cookie) -{ - QByteArray setData; - JsonInputStream setStr(setData); - setStr << "" << '\0' - << '[' << "removedExecutables" << ',' << "removedLibraries" << ']' - << '\0' << '[' - << '{' << QFileInfo(binaryIn).fileName() << ':' << QString::number(uid, 16) << '}' << ',' - << additionalLibraries - << ']'; - sendTcfTrkMessage(MessageWithoutReply, SettingsService, "set", setData, TcfTrkCallback(), cookie); -} - -void TcfTrkDevice::sendRunControlResumeCommand(const TcfTrkCallback &callBack, - const QByteArray &id, - RunControlResumeMode mode, - unsigned count, - quint64 rangeStart, - quint64 rangeEnd, - const QVariant &cookie) -{ - QByteArray resumeData; - JsonInputStream str(resumeData); - str << id << '\0' << int(mode) << '\0' << count; - switch (mode) { - case RM_STEP_OVER_RANGE: - case RM_STEP_INTO_RANGE: - case RM_REVERSE_STEP_OVER_RANGE: - case RM_REVERSE_STEP_INTO_RANGE: - str << '\0' << '{' << "RANGE_START" << ':' << rangeStart - << ',' << "RANGE_END" << ':' << rangeEnd << '}'; - break; - default: - break; - } - sendTcfTrkMessage(MessageWithReply, RunControlService, "resume", resumeData, callBack, cookie); -} - -void TcfTrkDevice::sendRunControlSuspendCommand(const TcfTrkCallback &callBack, - const QByteArray &id, - const QVariant &cookie) -{ - QByteArray data; - JsonInputStream str(data); - str << id; - sendTcfTrkMessage(MessageWithReply, RunControlService, "suspend", data, callBack, cookie); -} - -void TcfTrkDevice::sendRunControlResumeCommand(const TcfTrkCallback &callBack, - const QByteArray &id, - const QVariant &cookie) -{ - sendRunControlResumeCommand(callBack, id, RM_RESUME, 1, 0, 0, cookie); -} - -void TcfTrkDevice::sendBreakpointsAddCommand(const TcfTrkCallback &callBack, - const Breakpoint &bp, - const QVariant &cookie) -{ - QByteArray data; - JsonInputStream str(data); - str << bp; - sendTcfTrkMessage(MessageWithReply, BreakpointsService, "add", data, callBack, cookie); -} - -void TcfTrkDevice::sendBreakpointsRemoveCommand(const TcfTrkCallback &callBack, - const QByteArray &id, - const QVariant &cookie) -{ - sendBreakpointsRemoveCommand(callBack, QVector<QByteArray>(1, id), cookie); -} - -void TcfTrkDevice::sendBreakpointsRemoveCommand(const TcfTrkCallback &callBack, - const QVector<QByteArray> &ids, - const QVariant &cookie) -{ - QByteArray data; - JsonInputStream str(data); - str << ids; - sendTcfTrkMessage(MessageWithReply, BreakpointsService, "remove", data, callBack, cookie); -} - -void TcfTrkDevice::sendBreakpointsEnableCommand(const TcfTrkCallback &callBack, - const QByteArray &id, - bool enable, - const QVariant &cookie) -{ - sendBreakpointsEnableCommand(callBack, QVector<QByteArray>(1, id), enable, cookie); -} - -void TcfTrkDevice::sendBreakpointsEnableCommand(const TcfTrkCallback &callBack, - const QVector<QByteArray> &ids, - bool enable, - const QVariant &cookie) -{ - QByteArray data; - JsonInputStream str(data); - str << ids; - sendTcfTrkMessage(MessageWithReply, BreakpointsService, - enable ? "enable" : "disable", - data, callBack, cookie); -} - -void TcfTrkDevice::sendMemorySetCommand(const TcfTrkCallback &callBack, - const QByteArray &contextId, - quint64 start, const QByteArray& data, - const QVariant &cookie) -{ - QByteArray getData; - JsonInputStream str(getData); - // start/word size/mode. Mode should ideally be 1 (continue on error?) - str << contextId << '\0' << start << '\0' << 1 << '\0' << data.size() << '\0' << 1 - << '\0' << data.toBase64(); - sendTcfTrkMessage(MessageWithReply, MemoryService, "set", getData, callBack, cookie); -} - -void TcfTrkDevice::sendMemoryGetCommand(const TcfTrkCallback &callBack, - const QByteArray &contextId, - quint64 start, quint64 size, - const QVariant &cookie) -{ - QByteArray data; - JsonInputStream str(data); - // start/word size/mode. Mode should ideally be 1 (continue on error?) - str << contextId << '\0' << start << '\0' << 1 << '\0' << size << '\0' << 1; - sendTcfTrkMessage(MessageWithReply, MemoryService, "get", data, callBack, cookie); -} - -QByteArray TcfTrkDevice::parseMemoryGet(const TcfTrkCommandResult &r) -{ - if (r.type != TcfTrkCommandResult::SuccessReply || r.values.size() < 1) - return QByteArray(); - const JsonValue &memoryV = r.values.front(); - - if (memoryV.type() != JsonValue::String || memoryV.data().size() < 2 - || !memoryV.data().endsWith('=')) - return QByteArray(); - // Catch errors reported as hash: - // R.4."TlVMTA==".{"Time":1276786871255,"Code":1,"AltCode":-38,"AltOrg":"POSIX","Format":"BadDescriptor"} - // Not sure what to make of it. - if (r.values.size() >= 2 && r.values.at(1).type() == JsonValue::Object) - qWarning("Error retrieving memory: %s", r.values.at(1).toString(false).constData()); - // decode - const QByteArray memory = QByteArray::fromBase64(memoryV.data()); - if (memory.isEmpty()) - qWarning("Base64 decoding of %s failed.", memoryV.data().constData()); - if (debug) - qDebug("TcfTrkDevice::parseMemoryGet: received %d bytes", memory.size()); - return memory; -} - -void TcfTrkDevice::sendRegistersGetMCommand(const TcfTrkCallback &callBack, - const QByteArray &contextId, - const QVector<QByteArray> &ids, - const QVariant &cookie) -{ - // TODO: use "Registers" (which uses base64-encoded values) - QByteArray data; - JsonInputStream str(data); - str << contextId << '\0' << ids; - sendTcfTrkMessage(MessageWithReply, SimpleRegistersService, "get", data, callBack, cookie); -} - -void TcfTrkDevice::sendRegistersGetMRangeCommand(const TcfTrkCallback &callBack, - const QByteArray &contextId, - unsigned start, unsigned count) -{ - const unsigned end = start + count; - if (end > (unsigned)d->m_registerNames.size()) { - qWarning("TcfTrkDevice: No register name set for index %u (size: %d).", end, d->m_registerNames.size()); - return; - } - - QVector<QByteArray> ids; - ids.reserve(count); - for (unsigned i = start; i < end; i++) - ids.push_back(d->m_registerNames.at(i)); - sendRegistersGetMCommand(callBack, contextId, ids, QVariant(start)); -} - -// Set register -void TcfTrkDevice::sendRegistersSetCommand(const TcfTrkCallback &callBack, - const QByteArray &contextId, - const QByteArray &id, - unsigned value, - const QVariant &cookie) -{ - // TODO: use "Registers" (which uses base64-encoded values) - QByteArray data; - JsonInputStream str(data); - str << contextId << '\0' << QVector<QByteArray>(1, id) - << '\0' << QVector<QByteArray>(1, QByteArray::number(value, 16)); - sendTcfTrkMessage(MessageWithReply, SimpleRegistersService, "set", data, callBack, cookie); -} - -// Set register -void TcfTrkDevice::sendRegistersSetCommand(const TcfTrkCallback &callBack, - const QByteArray &contextId, - unsigned registerNumber, - unsigned value, - const QVariant &cookie) -{ - if (registerNumber >= (unsigned)d->m_registerNames.size()) { - qWarning("TcfTrkDevice: No register name set for index %u (size: %d).", registerNumber, d->m_registerNames.size()); - return; - } - sendRegistersSetCommand(callBack, contextId, - d->m_registerNames[registerNumber], - value, cookie); -} - -} // namespace tcftrk diff --git a/src/runonphone/symbianutils/tcftrkdevice.h b/src/runonphone/symbianutils/tcftrkdevice.h deleted file mode 100644 index d257cabae..000000000 --- a/src/runonphone/symbianutils/tcftrkdevice.h +++ /dev/null @@ -1,295 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the tools applications of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef TCFTRKENGINE_H -#define TCFTRKENGINE_H - -#include "symbianutils_global.h" -#include "tcftrkmessage.h" -#include "callback.h" -#include "json.h" - -#include <QtCore/QObject> -#include <QtCore/QSharedPointer> -#include <QtCore/QVector> -#include <QtCore/QVariant> -#include <QtCore/QStringList> - -QT_BEGIN_NAMESPACE -class QIODevice; -class QTextStream; -QT_END_NAMESPACE - -namespace tcftrk { - -struct TcfTrkDevicePrivate; -struct Breakpoint; - -/* Command error handling in TCF: - * 1) 'Severe' errors (JSON format, parameter format): Trk emits a - * nonstandard message (\3\2 error parameters) and closes the connection. - * 2) Protocol errors: 'N' without error message is returned. - * 3) Errors in command execution: 'R' with a TCF error hash is returned - * (see TcfTrkCommandError). */ - -/* Error code return in 'R' reply to command - * (see top of 'Services' documentation). */ -struct SYMBIANUTILS_EXPORT TcfTrkCommandError { - TcfTrkCommandError(); - void clear(); - operator bool() const { return timeMS != 0; } - QString toString() const; - void write(QTextStream &str) const; - bool parse(const QVector<JsonValue> &values); - - quint64 timeMS; // Since 1.1.1970 - int code; - QByteArray format; // message - // 'Alternative' meaning, like altOrg="POSIX"/altCode=<some errno> - QByteArray alternativeOrganization; - int alternativeCode; -}; - -/* Answer to a Tcf command passed to the callback. */ -struct SYMBIANUTILS_EXPORT TcfTrkCommandResult { - enum Type { - SuccessReply, // 'R' and no error -> all happy. - CommandErrorReply, // 'R' with TcfTrkCommandError received - ProgressReply, // 'P', progress indicator - FailReply // 'N' Protocol NAK, severe error - }; - - explicit TcfTrkCommandResult(Type t = SuccessReply); - explicit TcfTrkCommandResult(char typeChar, Services service, - const QByteArray &request, - const QVector<JsonValue> &values, - const QVariant &cookie); - - QString toString() const; - QString errorString() const; - operator bool() const { return type == SuccessReply || type == ProgressReply; } - - Type type; - Services service; - QByteArray request; - TcfTrkCommandError commandError; - QVector<JsonValue> values; - QVariant cookie; -}; - -typedef trk::Callback<const TcfTrkCommandResult &> TcfTrkCallback; - -/* TcfTrkDevice: TCF communication helper using an asynchronous QIODevice - * implementing the TCF protocol according to: -http://dev.eclipse.org/svnroot/dsdp/org.eclipse.tm.tcf/trunk/docs/TCF%20Specification.html -http://dev.eclipse.org/svnroot/dsdp/org.eclipse.tm.tcf/trunk/docs/TCF%20Services.html - * Commands can be sent along with callbacks that are passed a - * TcfTrkCommandResult and an opaque QVariant cookie. In addition, events are emitted. -*/ - -class SYMBIANUTILS_EXPORT TcfTrkDevice : public QObject -{ - Q_PROPERTY(unsigned verbose READ verbose WRITE setVerbose) - Q_OBJECT -public: - enum MessageType { MessageWithReply, - MessageWithoutReply, /* Non-standard: "Settings:set" command does not reply */ - NoopMessage }; - - typedef QSharedPointer<QIODevice> IODevicePtr; - - explicit TcfTrkDevice(QObject *parent = 0); - virtual ~TcfTrkDevice(); - - unsigned verbose() const; - - // Mapping of register names for indices - QVector<QByteArray> registerNames() const; - void setRegisterNames(const QVector<QByteArray>& n); - - IODevicePtr device() const; - IODevicePtr takeDevice(); - void setDevice(const IODevicePtr &dp); - - void sendTcfTrkMessage(MessageType mt, Services service, - const char *command, - const char *commandParameters, int commandParametersLength, - const TcfTrkCallback &callBack = TcfTrkCallback(), - const QVariant &cookie = QVariant()); - - void sendTcfTrkMessage(MessageType mt, Services service, const char *command, - const QByteArray &commandParameters, - const TcfTrkCallback &callBack = TcfTrkCallback(), - const QVariant &cookie = QVariant()); - - // Convenience messages: Start a process - void sendProcessStartCommand(const TcfTrkCallback &callBack, - const QString &binary, - unsigned uid, - QStringList arguments = QStringList(), - QString workingDirectory = QString(), - bool debugControl = true, - const QStringList &additionalLibraries = QStringList(), - const QVariant &cookie = QVariant()); - - // Preferred over Processes:Terminate by TCF TRK. - void sendRunControlTerminateCommand(const TcfTrkCallback &callBack, - const QByteArray &id, - const QVariant &cookie = QVariant()); - - void sendProcessTerminateCommand(const TcfTrkCallback &callBack, - const QByteArray &id, - const QVariant &cookie = QVariant()); - - // Non-standard: Remove executable from settings. - // Probably needs to be called after stopping. This command has no response. - void sendSettingsRemoveExecutableCommand(const QString &binaryIn, - unsigned uid, - const QStringList &additionalLibraries = QStringList(), - const QVariant &cookie = QVariant()); - - void sendRunControlSuspendCommand(const TcfTrkCallback &callBack, - const QByteArray &id, - const QVariant &cookie = QVariant()); - - // Resume / Step (see RunControlResumeMode). - void sendRunControlResumeCommand(const TcfTrkCallback &callBack, - const QByteArray &id, - RunControlResumeMode mode, - unsigned count /* = 1, currently ignored. */, - quint64 rangeStart, quint64 rangeEnd, - const QVariant &cookie = QVariant()); - - // Convenience to resume a suspended process - void sendRunControlResumeCommand(const TcfTrkCallback &callBack, - const QByteArray &id, - const QVariant &cookie = QVariant()); - - void sendBreakpointsAddCommand(const TcfTrkCallback &callBack, - const Breakpoint &b, - const QVariant &cookie = QVariant()); - - void sendBreakpointsRemoveCommand(const TcfTrkCallback &callBack, - const QByteArray &id, - const QVariant &cookie = QVariant()); - - void sendBreakpointsRemoveCommand(const TcfTrkCallback &callBack, - const QVector<QByteArray> &id, - const QVariant &cookie = QVariant()); - - void sendBreakpointsEnableCommand(const TcfTrkCallback &callBack, - const QByteArray &id, - bool enable, - const QVariant &cookie = QVariant()); - - void sendBreakpointsEnableCommand(const TcfTrkCallback &callBack, - const QVector<QByteArray> &id, - bool enable, - const QVariant &cookie = QVariant()); - - - void sendMemoryGetCommand(const TcfTrkCallback &callBack, - const QByteArray &contextId, - quint64 start, quint64 size, - const QVariant &cookie = QVariant()); - - void sendMemorySetCommand(const TcfTrkCallback &callBack, - const QByteArray &contextId, - quint64 start, const QByteArray& data, - const QVariant &cookie = QVariant()); - - // Reply is an array of hexvalues - void sendRegistersGetMCommand(const TcfTrkCallback &callBack, - const QByteArray &contextId, - const QVector<QByteArray> &ids, - const QVariant &cookie = QVariant()); - - // Convenience to get a range of register "R0" .. "R<n>". - // Cookie will be an int containing "start". - void sendRegistersGetMRangeCommand(const TcfTrkCallback &callBack, - const QByteArray &contextId, - unsigned start, unsigned count); - - // Set register - void sendRegistersSetCommand(const TcfTrkCallback &callBack, - const QByteArray &contextId, - const QByteArray &ids, - unsigned value, - const QVariant &cookie = QVariant()); - // Set register - void sendRegistersSetCommand(const TcfTrkCallback &callBack, - const QByteArray &contextId, - unsigned registerNumber, - unsigned value, - const QVariant &cookie = QVariant()); - - static QByteArray parseMemoryGet(const TcfTrkCommandResult &r); - -signals: - void genericTcfEvent(int service, const QByteArray &name, const QVector<tcftrk::JsonValue> &value); - void tcfEvent(const tcftrk::TcfTrkEvent &knownEvent); - - void logMessage(const QString &); - void error(const QString &); - -public slots: - void setVerbose(unsigned v); - -private slots: - void slotDeviceError(); - void slotDeviceSocketStateChanged(); - void slotDeviceReadyRead(); - -private: - bool checkOpen(); - void checkSendQueue(); - void writeMessage(QByteArray data); - void emitLogMessage(const QString &); - int parseMessage(const QByteArray &); - int parseTcfCommandReply(char type, const QVector<QByteArray> &tokens); - int parseTcfEvent(const QVector<QByteArray> &tokens); - - TcfTrkDevicePrivate *d; -}; - -} // namespace tcftrk - -#endif // TCFTRKENGINE_H diff --git a/src/runonphone/symbianutils/tcftrkmessage.cpp b/src/runonphone/symbianutils/tcftrkmessage.cpp deleted file mode 100644 index 76a3ec7f3..000000000 --- a/src/runonphone/symbianutils/tcftrkmessage.cpp +++ /dev/null @@ -1,562 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the tools applications of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "tcftrkmessage.h" -#include "json.h" - -#include <QtCore/QString> -#include <QtCore/QTextStream> - -// Names matching the enum -static const char *serviceNamesC[] = -{ "Locator", "RunControl", "Processes", "Memory", "Settings", "Breakpoints", - "Registers", "SimpleRegisters", - "UnknownService"}; - -namespace tcftrk { - -SYMBIANUTILS_EXPORT QString joinByteArrays(const QVector<QByteArray> &a, char sep) -{ - QString rc; - const int count = a.size(); - for (int i = 0; i < count; i++) { - if (i) - rc += QLatin1Char(sep); - rc += QString::fromUtf8(a.at(i)); - } - return rc; -} - -static inline bool jsonToBool(const JsonValue& js) -{ - return js.type() == JsonValue::Boolean && js.data() == "true"; -} - -SYMBIANUTILS_EXPORT const char *serviceName(Services s) -{ - return serviceNamesC[s]; -} - -SYMBIANUTILS_EXPORT Services serviceFromName(const char *n) -{ - const int count = sizeof(serviceNamesC)/sizeof(char *); - for (int i = 0; i < count; i++) - if (!qstrcmp(serviceNamesC[i], n)) - return static_cast<Services>(i); - return UnknownService; -} - -SYMBIANUTILS_EXPORT QString formatData(const QByteArray &a) -{ - const int columns = 16; - QString rc; - QTextStream str(&rc); - str.setIntegerBase(16); - str.setPadChar(QLatin1Char('0')); - const unsigned char *start = reinterpret_cast<const unsigned char *>(a.constData()); - const unsigned char *end = start + a.size(); - for (const unsigned char *p = start; p < end ; ) { - str << "0x"; - str.setFieldWidth(4); - str << (p - start); - str.setFieldWidth(0); - str << ' '; - QString asc; - int c = 0; - for ( ; c < columns && p < end; c++, p++) { - const unsigned u = *p; - str.setFieldWidth(2); - str << u; - str.setFieldWidth(0); - str << ' '; - switch (u) { - case '\n': - asc += QLatin1String("\\n"); - break; - case '\r': - asc += QLatin1String("\\r"); - break; - case '\t': - asc += QLatin1String("\\t"); - break; - default: - if (u >= 32 && u < 128) { - asc += QLatin1Char(' '); - asc += QLatin1Char(u); - } else { - asc += QLatin1String(" ."); - } - break; - } - } - if (const int remainder = columns - c) - str << QString(3 * remainder, QLatin1Char(' ')); - str << ' ' << asc << '\n'; - } - return rc; -} - -// ----------- RunControlContext -RunControlContext::RunControlContext() : - flags(0), resumeFlags(0) -{ -} - -void RunControlContext::clear() -{ - flags =0; - resumeFlags = 0; - id.clear(); - osid.clear(); - parentId.clear(); -} - -RunControlContext::Type RunControlContext::typeFromTcfId(const QByteArray &id) -{ - // "p12" or "p12.t34"? - return id.contains(".t") ? Thread : Process; -} - -unsigned RunControlContext::processId() const -{ - return processIdFromTcdfId(id); -} - -unsigned RunControlContext::threadId() const -{ - return threadIdFromTcdfId(id); -} - -unsigned RunControlContext::processIdFromTcdfId(const QByteArray &id) -{ - // Cut out process id from "p12" or "p12.t34"? - if (!id.startsWith('p')) - return 0; - const int dotPos = id.indexOf('.'); - const int pLen = dotPos == -1 ? id.size() : dotPos; - return id.mid(1, pLen - 1).toUInt(); -} - -unsigned RunControlContext::threadIdFromTcdfId(const QByteArray &id) -{ - const int tPos = id.indexOf(".t"); - return tPos != -1 ? id.mid(tPos + 2).toUInt() : uint(0); -} - -QByteArray RunControlContext::tcfId(unsigned processId, unsigned threadId /* = 0 */) -{ - QByteArray rc("p"); - rc += QByteArray::number(processId); - if (threadId) { - rc += ".t"; - rc += QByteArray::number(threadId); - } - return rc; -} - -RunControlContext::Type RunControlContext::type() const -{ - return RunControlContext::typeFromTcfId(id); -} - -bool RunControlContext::parse(const JsonValue &val) -{ - clear(); - if (val.type() != JsonValue::Object) - return false; - foreach(const JsonValue &c, val.children()) { - if (c.name() == "ID") { - id = c.data(); - } else if (c.name() == "OSID") { - osid = c.data(); - } else if (c.name() == "ParentID") { - parentId = c.data(); - } else if (c.name() == "IsContainer") { - if (jsonToBool(c)) - flags |= Container; - } else if (c.name() == "CanTerminate") { - if (jsonToBool(c)) - flags |= CanTerminate; - } else if (c.name() == "CanResume") { - resumeFlags = c.data().toUInt(); - } else if (c.name() == "HasState") { - if (jsonToBool(c)) - flags |= HasState; - } else if (c.name() == "CanSuspend") { - if (jsonToBool(c)) - flags |= CanSuspend; - } - } - return true; -} - -QString RunControlContext::toString() const -{ - QString rc; - QTextStream str(&rc); - format(str); - return rc; -} - -void RunControlContext::format(QTextStream &str) const -{ - str << " id='" << id << "' osid='" << osid - << "' parentId='" << parentId <<"' "; - if (flags & Container) - str << "[container] "; - if (flags & HasState) - str << "[has state] "; - if (flags & CanSuspend) - str << "[can suspend] "; - if (flags & CanSuspend) - str << "[can terminate] "; - str.setIntegerBase(16); - str << " resume_flags: 0x" << resumeFlags; - str.setIntegerBase(10); -} - -// ------ ModuleLoadEventInfo -ModuleLoadEventInfo::ModuleLoadEventInfo() : - loaded(false), codeAddress(0), dataAddress(0), requireResume(false) -{ -} - -void ModuleLoadEventInfo::clear() -{ - loaded = requireResume = false; - codeAddress = dataAddress =0; -} - -bool ModuleLoadEventInfo::parse(const JsonValue &val) -{ - clear(); - if (val.type() != JsonValue::Object) - return false; - foreach(const JsonValue &c, val.children()) { - if (c.name() == "Name") { - name = c.data(); - } else if (c.name() == "File") { - file = c.data(); - } else if (c.name() == "CodeAddress") { - codeAddress = c.data().toULongLong(); - } else if (c.name() == "DataAddress") { - dataAddress = c.data().toULongLong(); - } else if (c.name() == "Loaded") { - loaded = jsonToBool(c); - } else if (c.name() == "RequireResume") { - requireResume =jsonToBool(c); - } - } - return true; -} -void ModuleLoadEventInfo::format(QTextStream &str) const -{ - str << "name='" << name << "' file='" << file << "' " << - (loaded ? "[loaded] " : "[not loaded] "); - if (requireResume) - str << "[requires resume] "; - str.setIntegerBase(16); - str << " code: 0x" << codeAddress << " data: 0x" << dataAddress; - str.setIntegerBase(10); -} - -// ---------------------- Breakpoint - -// Types matching enum -static const char *breakPointTypesC[] = {"Software", "Hardware", "Auto"}; - -Breakpoint::Breakpoint(quint64 loc) : - type(Auto), enabled(true), ignoreCount(0), location(loc), size(1), thumb(true) -{ - if (loc) - id = idFromLocation(location); -} - -void Breakpoint::setContextId(unsigned processId, unsigned threadId) -{ - contextIds = QVector<QByteArray>(1, RunControlContext::tcfId(processId, threadId)); -} - -QByteArray Breakpoint::idFromLocation(quint64 loc) -{ - return QByteArray("BP_0x") + QByteArray::number(loc, 16); -} - -QString Breakpoint::toString() const -{ - QString rc; - QTextStream str(&rc); - str.setIntegerBase(16); - str << "Breakpoint '" << id << "' " << breakPointTypesC[type] << " for contexts '" - << joinByteArrays(contextIds, ',') << "' at 0x" << location; - str.setIntegerBase(10); - str << " size " << size; - if (enabled) - str << " [enabled]"; - if (thumb) - str << " [thumb]"; - if (ignoreCount) - str << " IgnoreCount " << ignoreCount; - return rc; -} - -JsonInputStream &operator<<(JsonInputStream &str, const Breakpoint &b) -{ - if (b.contextIds.isEmpty()) - qWarning("tcftrk::Breakpoint: No context ids specified"); - - str << '{' << "ID" << ':' << QString::fromUtf8(b.id) << ',' - << "BreakpointType" << ':' << breakPointTypesC[b.type] << ',' - << "Enabled" << ':' << b.enabled << ',' - << "IgnoreCount" << ':' << b.ignoreCount << ',' - << "ContextIds" << ':' << b.contextIds << ',' - << "Location" << ':' << QString::number(b.location) << ',' - << "Size" << ':' << b.size << ',' - << "THUMB_BREAKPOINT" << ':' << b.thumb - << '}'; - return str; -} - -// --- Events -TcfTrkEvent::TcfTrkEvent(Type type) : m_type(type) -{ -} - -TcfTrkEvent::~TcfTrkEvent() -{ -} - -TcfTrkEvent::Type TcfTrkEvent::type() const -{ - return m_type; -} - -QString TcfTrkEvent::toString() const -{ - return QString(); -} - -static const char sharedLibrarySuspendReasonC[] = "Shared Library"; - -TcfTrkEvent *TcfTrkEvent::parseEvent(Services s, const QByteArray &nameBA, const QVector<JsonValue> &values) -{ - switch (s) { - case LocatorService: - if (nameBA == "Hello" && values.size() == 1 && values.front().type() == JsonValue::Array) { - QStringList services; - foreach (const JsonValue &jv, values.front().children()) - services.push_back(QString::fromUtf8(jv.data())); - return new TcfTrkLocatorHelloEvent(services); - } - break; - case RunControlService: - if (values.empty()) - return 0; - // "id/PC/Reason/Data" - if (nameBA == "contextSuspended" && values.size() == 4) { - const QByteArray idBA = values.at(0).data(); - const quint64 pc = values.at(1).data().toULongLong(); - const QByteArray reasonBA = values.at(2).data(); - // Module load: Special - if (reasonBA == sharedLibrarySuspendReasonC) { - ModuleLoadEventInfo info; - if (!info.parse(values.at(3))) - return 0; - return new TcfTrkRunControlModuleLoadContextSuspendedEvent(idBA, reasonBA, pc, info); - } - return new TcfTrkRunControlContextSuspendedEvent(idBA, reasonBA, pc); - } // "contextSuspended" - if (nameBA == "contextAdded") - return TcfTrkRunControlContextAddedEvent::parseEvent(values); - if (nameBA == "contextRemoved" && values.front().type() == JsonValue::Array) { - QVector<QByteArray> ids; - foreach(const JsonValue &c, values.front().children()) - ids.push_back(c.data()); - return new TcfTrkRunControlContextRemovedEvent(ids); - } - break; - default: - break; - } - return 0; -} - -// -------------- TcfTrkServiceHelloEvent -TcfTrkLocatorHelloEvent::TcfTrkLocatorHelloEvent(const QStringList &s) : - TcfTrkEvent(LocatorHello), - m_services(s) -{ -} - -QString TcfTrkLocatorHelloEvent::toString() const -{ - return QLatin1String("ServiceHello: ") + m_services.join(QLatin1String(", ")); -} - -// -------------- TcfTrkIdEvent -TcfTrkIdEvent::TcfTrkIdEvent(Type t, const QByteArray &id) : - TcfTrkEvent(t), m_id(id) -{ -} - -// ---------- TcfTrkIdsEvent -TcfTrkIdsEvent::TcfTrkIdsEvent(Type t, const QVector<QByteArray> &ids) : - TcfTrkEvent(t), m_ids(ids) -{ -} - -QString TcfTrkIdsEvent::joinedIdString(const char sep) const -{ - return joinByteArrays(m_ids, sep); -} - -// ---------------- TcfTrkRunControlContextAddedEvent -TcfTrkRunControlContextAddedEvent::TcfTrkRunControlContextAddedEvent(const RunControlContexts &c) : - TcfTrkEvent(RunControlContextAdded), m_contexts(c) -{ -} - -TcfTrkRunControlContextAddedEvent - *TcfTrkRunControlContextAddedEvent::parseEvent(const QVector<JsonValue> &values) -{ - // Parse array of contexts - if (values.size() < 1 || values.front().type() != JsonValue::Array) - return 0; - - RunControlContexts contexts; - foreach (const JsonValue &v, values.front().children()) { - RunControlContext context; - if (context.parse(v)) - contexts.push_back(context); - } - return new TcfTrkRunControlContextAddedEvent(contexts); -} - -QString TcfTrkRunControlContextAddedEvent::toString() const -{ - QString rc; - QTextStream str(&rc); - str << "RunControl: " << m_contexts.size() << " context(s) " - << (type() == RunControlContextAdded ? "added" : "removed") - << '\n'; - foreach (const RunControlContext &c, m_contexts) { - c.format(str); - str << '\n'; - } - return rc; -} - -// --------------- TcfTrkRunControlContextRemovedEvent -TcfTrkRunControlContextRemovedEvent::TcfTrkRunControlContextRemovedEvent(const QVector<QByteArray> &ids) : - TcfTrkIdsEvent(RunControlContextRemoved, ids) -{ -} - -QString TcfTrkRunControlContextRemovedEvent::toString() const -{ - return QLatin1String("RunControl: Removed contexts '") + joinedIdString() + ("'."); -} - -// --------------- TcfTrkRunControlContextSuspendedEvent -TcfTrkRunControlContextSuspendedEvent::TcfTrkRunControlContextSuspendedEvent(const QByteArray &id, - const QByteArray &reason, - quint64 pc) : - TcfTrkIdEvent(RunControlSuspended, id), m_pc(pc), m_reason(reason) -{ -} - -TcfTrkRunControlContextSuspendedEvent::TcfTrkRunControlContextSuspendedEvent(Type t, - const QByteArray &id, - const QByteArray &reason, - quint64 pc) : - TcfTrkIdEvent(t, id), m_pc(pc), m_reason(reason) -{ -} - -void TcfTrkRunControlContextSuspendedEvent::format(QTextStream &str) const -{ - str.setIntegerBase(16); - str << "RunControl: '" << idString() << "' suspended at 0x" - << m_pc << ": '" << m_reason << "'."; - str.setIntegerBase(10); -} - -QString TcfTrkRunControlContextSuspendedEvent::toString() const -{ - QString rc; - QTextStream str(&rc); - format(str); - return rc; -} - -TcfTrkRunControlContextSuspendedEvent::Reason TcfTrkRunControlContextSuspendedEvent::reason() const -{ - if (m_reason == sharedLibrarySuspendReasonC) - return ModuleLoad; - if (m_reason == "Breakpoint") - return BreakPoint; - // 'Data abort exception'/'Thread has panicked' ... unfortunately somewhat unspecific. - if (m_reason.contains("exception") || m_reason.contains("panick")) - return Crash; - return Other; -} - -TcfTrkRunControlModuleLoadContextSuspendedEvent::TcfTrkRunControlModuleLoadContextSuspendedEvent(const QByteArray &id, - const QByteArray &reason, - quint64 pc, - const ModuleLoadEventInfo &mi) : - TcfTrkRunControlContextSuspendedEvent(RunControlModuleLoadSuspended, id, reason, pc), - m_mi(mi) -{ -} - -QString TcfTrkRunControlModuleLoadContextSuspendedEvent::toString() const -{ - QString rc; - QTextStream str(&rc); - TcfTrkRunControlContextSuspendedEvent::format(str); - str << ' '; - m_mi.format(str); - return rc; -} - - -} // namespace tcftrk diff --git a/src/runonphone/symbianutils/tcftrkmessage.h b/src/runonphone/symbianutils/tcftrkmessage.h deleted file mode 100644 index 77b202462..000000000 --- a/src/runonphone/symbianutils/tcftrkmessage.h +++ /dev/null @@ -1,296 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the tools applications of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef TRCFTRKMESSAGE_H -#define TRCFTRKMESSAGE_H - -#include "symbianutils_global.h" - -#include <QtCore/QStringList> -#include <QtCore/QVector> - -QT_BEGIN_NAMESPACE -class QTextStream; -QT_END_NAMESPACE - -namespace tcftrk { - -class JsonValue; -class JsonInputStream; - -enum Services { - LocatorService, - RunControlService, - ProcessesService, - MemoryService, - SettingsService, // non-standard, trk specific - BreakpointsService, - RegistersService, - SimpleRegistersService, // non-standard, trk specific - UnknownService -}; // Note: Check string array 'serviceNamesC' of same size when modifying this. - -// Modes of RunControl/'Resume' (see EDF documentation). -// As of 24.6.2010, RM_RESUME, RM_STEP_OVER, RM_STEP_INTO, -// RM_STEP_OVER_RANGE, RM_STEP_INTO_RANGE are supported with -// RANG_START/RANGE_END parameters. -enum RunControlResumeMode { - RM_RESUME = 0, - RM_STEP_OVER = 1, RM_STEP_INTO = 2, - RM_STEP_OVER_LINE = 3, RM_STEP_INTO_LINE = 4, - RM_STEP_OUT = 5, RM_REVERSE_RESUME = 6, - RM_REVERSE_STEP_OVER = 7, RM_REVERSE_STEP_INTO = 8, - RM_REVERSE_STEP_OVER_LINE = 9, RM_REVERSE_STEP_INTO_LINE = 10, - RM_REVERSE_STEP_OUT = 11, RM_STEP_OVER_RANGE = 12, - RM_STEP_INTO_RANGE = 13, RM_REVERSE_STEP_OVER_RANGE = 14, - RM_REVERSE_STEP_INTO_RANGE = 15 -}; - -SYMBIANUTILS_EXPORT const char *serviceName(Services s); -SYMBIANUTILS_EXPORT Services serviceFromName(const char *); - -// Debug helpers -SYMBIANUTILS_EXPORT QString formatData(const QByteArray &a); -SYMBIANUTILS_EXPORT QString joinByteArrays(const QVector<QByteArray> &a, char sep = ','); - -// Context used in 'RunControl contextAdded' events and in reply -// to 'Processes start'. Could be thread or process. -struct SYMBIANUTILS_EXPORT RunControlContext { - enum Flags { - Container = 0x1, HasState = 0x2, CanSuspend = 0x4, - CanTerminate = 0x8 - }; - enum Type { Process, Thread }; - - RunControlContext(); - Type type() const; - unsigned processId() const; - unsigned threadId() const; - - void clear(); - bool parse(const JsonValue &v); - void format(QTextStream &str) const; - QString toString() const; - - // Helper for converting the TCF ids ("p12" or "p12.t34") - static Type typeFromTcfId(const QByteArray &id); - static unsigned processIdFromTcdfId(const QByteArray &id); - static unsigned threadIdFromTcdfId(const QByteArray &id); - static QByteArray tcfId(unsigned processId, unsigned threadId = 0); - - unsigned flags; - unsigned resumeFlags; - QByteArray id; // "p434.t699" - QByteArray osid; // Non-standard: Process or thread id - QByteArray parentId; // Parent process id of a thread. -}; - -// Module load information occurring with 'RunControl contextSuspended' events -struct SYMBIANUTILS_EXPORT ModuleLoadEventInfo { - ModuleLoadEventInfo(); - void clear(); - bool parse(const JsonValue &v); - void format(QTextStream &str) const; - - QByteArray name; - QByteArray file; - bool loaded; - quint64 codeAddress; - quint64 dataAddress; - bool requireResume; -}; - -// Breakpoint as supported by TcfTrk source June 2010 -// TODO: Add watchpoints,etc once they are implemented -struct SYMBIANUTILS_EXPORT Breakpoint { - enum Type { Software, Hardware, Auto }; - - explicit Breakpoint(quint64 loc = 0); - void setContextId(unsigned processId, unsigned threadId = 0); - QString toString() const; - - static QByteArray idFromLocation(quint64 loc); // Automagically determine from location - - Type type; - bool enabled; - int ignoreCount; - QVector<QByteArray> contextIds; // Process or thread ids. - QByteArray id; // Id of the breakpoint; - quint64 location; - unsigned size; - bool thumb; -}; - -SYMBIANUTILS_EXPORT JsonInputStream &operator<<(JsonInputStream &str, const Breakpoint &b); - -// Event hierarchy -class SYMBIANUTILS_EXPORT TcfTrkEvent { - Q_DISABLE_COPY(TcfTrkEvent) -public: - enum Type { None, - LocatorHello, - RunControlContextAdded, - RunControlContextRemoved, - RunControlSuspended, - RunControlBreakpointSuspended, - RunControlModuleLoadSuspended, - RunControlResumed - }; - - virtual ~TcfTrkEvent(); - - Type type() const; - virtual QString toString() const; - - static TcfTrkEvent *parseEvent(Services s, const QByteArray &name, const QVector<JsonValue> &val); - -protected: - explicit TcfTrkEvent(Type type = None); - -private: - const Type m_type; -}; - -// ServiceHello -class SYMBIANUTILS_EXPORT TcfTrkLocatorHelloEvent : public TcfTrkEvent { -public: - explicit TcfTrkLocatorHelloEvent(const QStringList &); - - const QStringList &services() { return m_services; } - virtual QString toString() const; - -private: - QStringList m_services; -}; - -// Base for events that just have one id as parameter -// (simple suspend) -class SYMBIANUTILS_EXPORT TcfTrkIdEvent : public TcfTrkEvent { -protected: - explicit TcfTrkIdEvent(Type t, const QByteArray &id); -public: - QByteArray id() const { return m_id; } - QString idString() const { return QString::fromUtf8(m_id); } - -private: - const QByteArray m_id; -}; - -// Base for events that just have some ids as parameter -// (context removed) -class SYMBIANUTILS_EXPORT TcfTrkIdsEvent : public TcfTrkEvent { -protected: - explicit TcfTrkIdsEvent(Type t, const QVector<QByteArray> &ids); - -public: - QVector<QByteArray> ids() const { return m_ids; } - QString joinedIdString(const char sep = ',') const; - -private: - const QVector<QByteArray> m_ids; -}; - -// RunControlContextAdded -class SYMBIANUTILS_EXPORT TcfTrkRunControlContextAddedEvent : public TcfTrkEvent { -public: - typedef QVector<RunControlContext> RunControlContexts; - - explicit TcfTrkRunControlContextAddedEvent(const RunControlContexts &c); - - const RunControlContexts &contexts() const { return m_contexts; } - virtual QString toString() const; - - static TcfTrkRunControlContextAddedEvent *parseEvent(const QVector<JsonValue> &val); - -private: - const RunControlContexts m_contexts; -}; - -// RunControlContextRemoved -class SYMBIANUTILS_EXPORT TcfTrkRunControlContextRemovedEvent : public TcfTrkIdsEvent { -public: - explicit TcfTrkRunControlContextRemovedEvent(const QVector<QByteArray> &id); - virtual QString toString() const; -}; - -// Simple RunControlContextSuspended (process/thread) -class SYMBIANUTILS_EXPORT TcfTrkRunControlContextSuspendedEvent : public TcfTrkIdEvent { -public: - enum Reason { BreakPoint, ModuleLoad, Crash, Other } ; - - explicit TcfTrkRunControlContextSuspendedEvent(const QByteArray &id, - const QByteArray &reason, - quint64 pc = 0); - virtual QString toString() const; - - quint64 pc() const { return m_pc; } - QByteArray reasonID() const { return m_reason; } - Reason reason() const; - -protected: - explicit TcfTrkRunControlContextSuspendedEvent(Type t, - const QByteArray &id, - const QByteArray &reason, - quint64 pc = 0); - void format(QTextStream &str) const; - -private: - const quint64 m_pc; - const QByteArray m_reason; -}; - -// RunControlContextSuspended due to module load -class SYMBIANUTILS_EXPORT TcfTrkRunControlModuleLoadContextSuspendedEvent : public TcfTrkRunControlContextSuspendedEvent { -public: - explicit TcfTrkRunControlModuleLoadContextSuspendedEvent(const QByteArray &id, - const QByteArray &reason, - quint64 pc, - const ModuleLoadEventInfo &mi); - - virtual QString toString() const; - const ModuleLoadEventInfo &info() const { return m_mi; } - -private: - const ModuleLoadEventInfo m_mi; -}; - -} // namespace tcftrk -#endif // TRCFTRKMESSAGE_H diff --git a/src/runonphone/symbianutils/trkdevice.cpp b/src/runonphone/symbianutils/trkdevice.cpp deleted file mode 100644 index 8dd117043..000000000 --- a/src/runonphone/symbianutils/trkdevice.cpp +++ /dev/null @@ -1,1184 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the tools applications of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "trkdevice.h" -#include "trkutils.h" -#include "trkutils_p.h" - -#include <QtCore/QString> -#include <QtCore/QDebug> -#include <QtCore/QQueue> -#include <QtCore/QHash> -#include <QtCore/QMap> -#include <QtCore/QThread> -#include <QtCore/QMutex> -#include <QtCore/QWaitCondition> -#include <QtCore/QSharedPointer> -#include <QtCore/QScopedPointer> -#include <QtCore/QMetaType> - -#ifdef Q_OS_WIN -# include <windows.h> -#else -# include <QtCore/QFile> - -# include <stdio.h> -# include <sys/ioctl.h> -# include <sys/types.h> -# include <termios.h> -# include <errno.h> -# include <string.h> -# include <unistd.h> -/* Required headers for select() according to POSIX.1-2001 */ -# include <sys/select.h> -/* Required headers for select() according to earlier standards: - #include <sys/time.h> - #include <sys/types.h> - #include <unistd.h> -*/ -#endif - -#ifdef Q_OS_WIN - -// Format windows error from GetLastError() value: -// TODO: Use the one provided by the utils lib. -QString winErrorMessage(unsigned long error) -{ - QString rc = QString::fromLatin1("#%1: ").arg(error); - ushort *lpMsgBuf; - - const int len = FormatMessage( - FORMAT_MESSAGE_ALLOCATE_BUFFER - | FORMAT_MESSAGE_FROM_SYSTEM - | FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, error, 0, (LPTSTR)&lpMsgBuf, 0, NULL); - if (len) { - rc = QString::fromUtf16(lpMsgBuf, len); - LocalFree(lpMsgBuf); - } else { - rc += QString::fromLatin1("<unknown error>"); - } - return rc; -} - -#endif - -enum { verboseTrk = 0 }; - -static inline QString msgAccessingClosedDevice(const QString &msg) -{ - return QString::fromLatin1("Error: Attempt to access device '%1', which is closed.").arg(msg); -} - -namespace trk { - -/////////////////////////////////////////////////////////////////////// -// -// TrkMessage -// -/////////////////////////////////////////////////////////////////////// - -/* A message to be send to TRK, triggering a callback on receipt - * of the answer. */ -struct TrkMessage -{ - explicit TrkMessage(byte code = 0u, byte token = 0u, - TrkCallback callback = TrkCallback()); - - byte code; - byte token; - QByteArray data; - QVariant cookie; - TrkCallback callback; -}; - -TrkMessage::TrkMessage(byte c, byte t, TrkCallback cb) : - code(c), - token(t), - callback(cb) -{ -} - -QDebug operator<<(QDebug d, const TrkMessage &msg) -{ - return d << "Message: Code: " << msg.code - << " Token: " << msg.token << " " << msg.data.toHex(); -} - -} // namespace trk - -Q_DECLARE_METATYPE(trk::TrkMessage) -Q_DECLARE_METATYPE(trk::TrkResult) - -namespace trk { - -/////////////////////////////////////////////////////////////////////// -// -// TrkWriteQueue: Mixin class that manages a write queue of Trk messages. -// pendingMessage()/notifyWriteResult() should be called from a worked/timer -// that writes the messages. The class does not take precautions for multithreading. -// A no-op message is simply taken off the queue. The calling class -// can use the helper invokeNoopMessage() to trigger its callback. -// -/////////////////////////////////////////////////////////////////////// - -class TrkWriteQueue -{ - Q_DISABLE_COPY(TrkWriteQueue) -public: - explicit TrkWriteQueue(); - void clear(); - - // Enqueue messages. - void queueTrkMessage(byte code, TrkCallback callback, - const QByteArray &data, const QVariant &cookie); - void queueTrkInitialPing(); - - // Call this from the device read notification with the results. - void slotHandleResult(const TrkResult &result, QMutex *mutex = 0); - - // pendingMessage() can be called periodically in a timer to retrieve - // the pending messages to be sent. - enum PendingMessageResult { - NoMessage, // No message in queue. - PendingMessage, /* There is a queued message. The calling class - * can write it out and use notifyWriteResult() - * to notify about the result. */ - NoopMessageDequeued // A no-op message has been dequeued. see invokeNoopMessage(). - }; - - PendingMessageResult pendingMessage(TrkMessage *message); - // Notify the queue about the success of the write operation - // after taking the pendingMessage off. - enum WriteResult { - WriteOk, - WriteFailedDiscard, // Discard failed message - WriteFailedKeep, // Keep failed message - }; - void notifyWriteResult(WriteResult ok); - - // Helper function that invokes the callback of a no-op message - static void invokeNoopMessage(trk::TrkMessage); - -private: - typedef QMap<byte, TrkMessage> TokenMessageMap; - - byte nextTrkWriteToken(); - - byte m_trkWriteToken; - QQueue<TrkMessage> m_trkWriteQueue; - TokenMessageMap m_writtenTrkMessages; - bool m_trkWriteBusy; -}; - -TrkWriteQueue::TrkWriteQueue() : - m_trkWriteToken(0), - m_trkWriteBusy(false) -{ -} - -void TrkWriteQueue::clear() -{ - m_trkWriteToken = 0; - m_trkWriteBusy = false; - m_trkWriteQueue.clear(); - const int discarded = m_writtenTrkMessages.size(); - m_writtenTrkMessages.clear(); - if (verboseTrk) - qDebug() << "TrkWriteQueue::clear: discarded " << discarded; -} - -byte TrkWriteQueue::nextTrkWriteToken() -{ - ++m_trkWriteToken; - if (m_trkWriteToken == 0) - ++m_trkWriteToken; - if (verboseTrk) - qDebug() << "nextTrkWriteToken:" << m_trkWriteToken; - return m_trkWriteToken; -} - -void TrkWriteQueue::queueTrkMessage(byte code, TrkCallback callback, - const QByteArray &data, const QVariant &cookie) -{ - const byte token = code == TRK_WRITE_QUEUE_NOOP_CODE ? - byte(0) : nextTrkWriteToken(); - TrkMessage msg(code, token, callback); - msg.data = data; - msg.cookie = cookie; - m_trkWriteQueue.append(msg); -} - -TrkWriteQueue::PendingMessageResult TrkWriteQueue::pendingMessage(TrkMessage *message) -{ - // Invoked from timer, try to flush out message queue - if (m_trkWriteBusy || m_trkWriteQueue.isEmpty()) - return NoMessage; - // Handle the noop message, just invoke CB in slot (ower thread) - if (m_trkWriteQueue.front().code == TRK_WRITE_QUEUE_NOOP_CODE) { - *message = m_trkWriteQueue.dequeue(); - return NoopMessageDequeued; - } - // Insert into map fir answers (as reading threads might get an - // answer before notifyWriteResult(true)) is called. - *message = m_trkWriteQueue.front(); - m_writtenTrkMessages.insert(message->token, *message); - m_trkWriteBusy = true; - return PendingMessage; -} - -void TrkWriteQueue::invokeNoopMessage(trk::TrkMessage noopMessage) -{ - TrkResult result; - result.code = noopMessage.code; - result.token = noopMessage.token; - result.data = noopMessage.data; - result.cookie = noopMessage.cookie; - noopMessage.callback(result); -} - -void TrkWriteQueue::notifyWriteResult(WriteResult wr) -{ - // On success, dequeue message and await result - const byte token = m_trkWriteQueue.front().token; - switch (wr) { - case WriteOk: - m_trkWriteQueue.dequeue(); - break; - case WriteFailedKeep: - case WriteFailedDiscard: - m_writtenTrkMessages.remove(token); - m_trkWriteBusy = false; - if (wr == WriteFailedDiscard) - m_trkWriteQueue.dequeue(); - break; - } -} - -void TrkWriteQueue::slotHandleResult(const TrkResult &result, QMutex *mutex) -{ - // Find which request the message belongs to and invoke callback - // if ACK or on NAK if desired. - if (mutex) - mutex->lock(); - m_trkWriteBusy = false; - const TokenMessageMap::iterator it = m_writtenTrkMessages.find(result.token); - if (it == m_writtenTrkMessages.end()) { - if (mutex) - mutex->unlock(); - return; - } - TrkCallback callback = it.value().callback; - const QVariant cookie = it.value().cookie; - m_writtenTrkMessages.erase(it); - if (mutex) - mutex->unlock(); - // Invoke callback - if (callback) { - TrkResult result1 = result; - result1.cookie = cookie; - callback(result1); - } -} - -void TrkWriteQueue::queueTrkInitialPing() -{ - // Ping, reset sequence count - m_trkWriteToken = 0; - m_trkWriteQueue.append(TrkMessage(TrkPing, 0)); -} - -/////////////////////////////////////////////////////////////////////// -// -// DeviceContext to be shared between threads -// -/////////////////////////////////////////////////////////////////////// - -struct DeviceContext { - DeviceContext(); -#ifdef Q_OS_WIN - HANDLE device; - OVERLAPPED readOverlapped; - OVERLAPPED writeOverlapped; -#else - QFile file; -#endif - bool serialFrame; - QMutex mutex; -}; - -DeviceContext::DeviceContext() : -#ifdef Q_OS_WIN - device(INVALID_HANDLE_VALUE), -#endif - serialFrame(true) -{ -} - -/////////////////////////////////////////////////////////////////////// -// -// TrkWriterThread: A thread operating a TrkWriteQueue. -// with exception of the handling of the TRK_WRITE_QUEUE_NOOP_CODE -// synchronization message. The invocation of the callback is then -// done by the thread owning the TrkWriteQueue, while pendingMessage() is called -// from another thread. This happens via a Qt::BlockingQueuedConnection. - -/////////////////////////////////////////////////////////////////////// - -class WriterThread : public QThread -{ - Q_OBJECT - Q_DISABLE_COPY(WriterThread) -public: - explicit WriterThread(const QSharedPointer<DeviceContext> &context); - - // Enqueue messages. - void queueTrkMessage(byte code, TrkCallback callback, - const QByteArray &data, const QVariant &cookie); - void queueTrkInitialPing(); - - void clearWriteQueue(); - - // Call this from the device read notification with the results. - void slotHandleResult(const TrkResult &result); - - virtual void run(); - -signals: - void error(const QString &); - void internalNoopMessageDequeued(const trk::TrkMessage&); - -public slots: - bool trkWriteRawMessage(const TrkMessage &msg); - void terminate(); - void tryWrite(); - -private slots: - void invokeNoopMessage(const trk::TrkMessage &); - -private: - bool write(const QByteArray &data, QString *errorMessage); - inline int writePendingMessage(); - - const QSharedPointer<DeviceContext> m_context; - QMutex m_dataMutex; - QMutex m_waitMutex; - QWaitCondition m_waitCondition; - TrkWriteQueue m_queue; - bool m_terminate; -}; - -WriterThread::WriterThread(const QSharedPointer<DeviceContext> &context) : - m_context(context), - m_terminate(false) -{ - static const int trkMessageMetaId = qRegisterMetaType<trk::TrkMessage>(); - Q_UNUSED(trkMessageMetaId) - connect(this, SIGNAL(internalNoopMessageDequeued(trk::TrkMessage)), - this, SLOT(invokeNoopMessage(trk::TrkMessage)), Qt::BlockingQueuedConnection); -} - -void WriterThread::run() -{ - while (writePendingMessage() == 0) ; -} - -int WriterThread::writePendingMessage() -{ - enum { MaxAttempts = 100, RetryIntervalMS = 200 }; - - // Wait. Use a timeout in case something is already queued before we - // start up or some weird hanging exit condition - m_waitMutex.lock(); - m_waitCondition.wait(&m_waitMutex, 100); - m_waitMutex.unlock(); - if (m_terminate) - return 1; - - // Send off message - m_dataMutex.lock(); - TrkMessage message; - const TrkWriteQueue::PendingMessageResult pr = m_queue.pendingMessage(&message); - m_dataMutex.unlock(); - - switch (pr) { - case TrkWriteQueue::NoMessage: - break; - case TrkWriteQueue::PendingMessage: { - //qDebug() << "Write pending message " << message; - // Untested: try to re-send a few times - bool success = false; - for (int r = 0; !success && (r < MaxAttempts); r++) { - success = trkWriteRawMessage(message); - if (!success) { - emit error(QString::fromLatin1("Write failure, attempt %1 of %2.").arg(r).arg(int(MaxAttempts))); - if (m_terminate) - return 1; - QThread::msleep(RetryIntervalMS); - } - } - // Notify queue. If still failed, give up. - m_dataMutex.lock(); - m_queue.notifyWriteResult(success ? TrkWriteQueue::WriteOk : TrkWriteQueue::WriteFailedDiscard); - m_dataMutex.unlock(); - } - break; - case TrkWriteQueue::NoopMessageDequeued: - // Sync with thread that owns us via a blocking signal - if (verboseTrk) - qDebug() << "Noop message dequeued" << message; - emit internalNoopMessageDequeued(message); - break; - } // switch - return 0; -} - -void WriterThread::invokeNoopMessage(const trk::TrkMessage &msg) -{ - TrkWriteQueue::invokeNoopMessage(msg); -} - -void WriterThread::terminate() -{ - m_terminate = true; - m_waitCondition.wakeAll(); - wait(); - m_terminate = false; - m_queue.clear(); -} - -#ifdef Q_OS_WIN - -static inline QString msgTerminated(int size) -{ - return QString::fromLatin1("Terminated with %1 bytes pending.").arg(size); -} - -// Interruptible synchronous write function. -static inline bool overlappedSyncWrite(HANDLE file, - const bool &terminateFlag, - const char *data, - DWORD size, DWORD *charsWritten, - OVERLAPPED *overlapped, - QString *errorMessage) -{ - if (WriteFile(file, data, size, charsWritten, overlapped)) - return true; - const DWORD writeError = GetLastError(); - if (writeError != ERROR_IO_PENDING) { - *errorMessage = QString::fromLatin1("WriteFile failed: %1").arg(winErrorMessage(writeError)); - return false; - } - // Wait for written or thread terminated - const DWORD timeoutMS = 200; - const unsigned maxAttempts = 20; - DWORD wr = WaitForSingleObject(overlapped->hEvent, timeoutMS); - for (unsigned n = 0; wr == WAIT_TIMEOUT && n < maxAttempts && !terminateFlag; - wr = WaitForSingleObject(overlapped->hEvent, timeoutMS), n++); - if (terminateFlag) { - *errorMessage = msgTerminated(size); - return false; - } - switch (wr) { - case WAIT_OBJECT_0: - break; - case WAIT_TIMEOUT: - *errorMessage = QString::fromLatin1("Write timed out."); - return false; - default: - *errorMessage = QString::fromLatin1("Error while waiting for WriteFile results: %1").arg(winErrorMessage(GetLastError())); - return false; - } - if (!GetOverlappedResult(file, overlapped, charsWritten, TRUE)) { - *errorMessage = QString::fromLatin1("Error writing %1 bytes: %2").arg(size).arg(winErrorMessage(GetLastError())); - return false; - } - return true; -} -#endif - -bool WriterThread::write(const QByteArray &data, QString *errorMessage) -{ - if (verboseTrk) - qDebug() << "Write raw data: " << stringFromArray(data).toLatin1(); - QMutexLocker locker(&m_context->mutex); -#ifdef Q_OS_WIN - DWORD charsWritten; - if (!overlappedSyncWrite(m_context->device, m_terminate, data.data(), data.size(), &charsWritten, &m_context->writeOverlapped, errorMessage)) { - return false; - } - FlushFileBuffers(m_context->device); - return true; -#else - if (m_context->file.write(data) == -1 || !m_context->file.flush()) { - *errorMessage = QString::fromLatin1("Cannot write: %1").arg(m_context->file.errorString()); - return false; - } - return true; -#endif -} - -bool WriterThread::trkWriteRawMessage(const TrkMessage &msg) -{ - const QByteArray ba = frameMessage(msg.code, msg.token, msg.data, m_context->serialFrame); - QString errorMessage; - const bool rc = write(ba, &errorMessage); - if (!rc) { - qWarning("%s\n", qPrintable(errorMessage)); - emit error(errorMessage); - } - return rc; -} - -void WriterThread::tryWrite() -{ - m_waitCondition.wakeAll(); -} - -void WriterThread::queueTrkMessage(byte code, TrkCallback callback, - const QByteArray &data, const QVariant &cookie) -{ - m_dataMutex.lock(); - m_queue.queueTrkMessage(code, callback, data, cookie); - m_dataMutex.unlock(); - tryWrite(); -} - -void WriterThread::clearWriteQueue() -{ - m_dataMutex.lock(); - m_queue.clear(); - m_dataMutex.unlock(); -} - -void WriterThread::queueTrkInitialPing() -{ - m_dataMutex.lock(); - m_queue.queueTrkInitialPing(); - m_dataMutex.unlock(); - tryWrite(); -} - -// Call this from the device read notification with the results. -void WriterThread::slotHandleResult(const TrkResult &result) -{ - m_queue.slotHandleResult(result, &m_dataMutex); - tryWrite(); // Have messages been enqueued in-between? -} - - -/////////////////////////////////////////////////////////////////////// -// -// ReaderThreadBase: Base class for a thread that reads data from -// the device, decodes the messages and emit signals for the messages. -// A Qt::BlockingQueuedConnection should be used for the message signal -// to ensure messages are processed in the correct sequence. -// -/////////////////////////////////////////////////////////////////////// - -class ReaderThreadBase : public QThread -{ - Q_OBJECT - Q_DISABLE_COPY(ReaderThreadBase) -public: - - int bytesPending() const { return m_trkReadBuffer.size(); } - -signals: - void messageReceived(const trk::TrkResult &result, const QByteArray &rawData); - -protected: - explicit ReaderThreadBase(const QSharedPointer<DeviceContext> &context); - void processData(const QByteArray &a); - void processData(char c); - - const QSharedPointer<DeviceContext> m_context; - -private: - void readMessages(); - - QByteArray m_trkReadBuffer; - bool linkEstablishmentMode; -}; - -ReaderThreadBase::ReaderThreadBase(const QSharedPointer<DeviceContext> &context) : - m_context(context), linkEstablishmentMode(true) -{ - static const int trkResultMetaId = qRegisterMetaType<trk::TrkResult>(); - Q_UNUSED(trkResultMetaId) -} - -void ReaderThreadBase::processData(const QByteArray &a) -{ - m_trkReadBuffer += a; - readMessages(); -} - -void ReaderThreadBase::processData(char c) -{ - m_trkReadBuffer += c; - if (m_trkReadBuffer.size() > 1) - readMessages(); -} - -void ReaderThreadBase::readMessages() -{ - TrkResult r; - QByteArray rawData; - while (extractResult(&m_trkReadBuffer, m_context->serialFrame, &r, linkEstablishmentMode, &rawData)) { - emit messageReceived(r, rawData); - } -} - -#ifdef Q_OS_WIN -/////////////////////////////////////////////////////////////////////// -// -// WinReaderThread: A thread reading from the device using Windows API. -// Waits on an overlapped I/O handle and an event that tells the thread to -// terminate. -// -/////////////////////////////////////////////////////////////////////// - -class WinReaderThread : public ReaderThreadBase -{ - Q_OBJECT - Q_DISABLE_COPY(WinReaderThread) -public: - explicit WinReaderThread(const QSharedPointer<DeviceContext> &context); - ~WinReaderThread(); - - virtual void run(); - -signals: - void error(const QString &); - -public slots: - void terminate(); - -private: - enum Handles { FileHandle, TerminateEventHandle, HandleCount }; - - inline int tryRead(); - - HANDLE m_handles[HandleCount]; -}; - -WinReaderThread::WinReaderThread(const QSharedPointer<DeviceContext> &context) : - ReaderThreadBase(context) -{ - m_handles[FileHandle] = NULL; - m_handles[TerminateEventHandle] = CreateEvent(NULL, FALSE, FALSE, NULL); -} - -WinReaderThread::~WinReaderThread() -{ - CloseHandle(m_handles[TerminateEventHandle]); -} - -// Return 0 to continue or error code -int WinReaderThread::tryRead() -{ - enum { BufSize = 1024 }; - char buffer[BufSize]; - // Check if there are already bytes waiting. If not, wait for first byte - COMSTAT comStat; - if (!ClearCommError(m_context->device, NULL, &comStat)){ - emit error(QString::fromLatin1("ClearCommError failed: %1").arg(winErrorMessage(GetLastError()))); - return -7; - } - const DWORD bytesToRead = qMax(DWORD(1), qMin(comStat.cbInQue, DWORD(BufSize))); - // Trigger read - DWORD bytesRead = 0; - if (ReadFile(m_context->device, &buffer, bytesToRead, &bytesRead, &m_context->readOverlapped)) { - if (bytesRead == 1) { - processData(buffer[0]); - } else { - processData(QByteArray(buffer, bytesRead)); - } - return 0; - } - const DWORD readError = GetLastError(); - if (readError != ERROR_IO_PENDING) { - emit error(QString::fromLatin1("Read error: %1").arg(winErrorMessage(readError))); - return -1; - } - // Wait for either termination or data - const DWORD wr = WaitForMultipleObjects(HandleCount, m_handles, false, INFINITE); - if (wr == WAIT_FAILED) { - emit error(QString::fromLatin1("Wait failed: %1").arg(winErrorMessage(GetLastError()))); - return -2; - } - if (wr - WAIT_OBJECT_0 == TerminateEventHandle) { - return 1; // Terminate - } - // Check data - if (!GetOverlappedResult(m_context->device, &m_context->readOverlapped, &bytesRead, true)) { - emit error(QString::fromLatin1("GetOverlappedResult failed: %1").arg(winErrorMessage(GetLastError()))); - return -3; - } - if (bytesRead == 1) { - processData(buffer[0]); - } else { - processData(QByteArray(buffer, bytesRead)); - } - return 0; -} - -void WinReaderThread::run() -{ - m_handles[FileHandle] = m_context->readOverlapped.hEvent; - while ( tryRead() == 0) ; -} - -void WinReaderThread::terminate() -{ - SetEvent(m_handles[TerminateEventHandle]); - wait(); -} - -typedef WinReaderThread ReaderThread; - -#else - -/////////////////////////////////////////////////////////////////////// -// -// UnixReaderThread: A thread reading from the device. -// Uses select() to wait and a special ioctl() to find out the number -// of bytes queued. For clean termination, the self-pipe trick is used. -// The class maintains a pipe, on whose read end the select waits besides -// the device file handle. To terminate, a byte is written to the pipe. -// -/////////////////////////////////////////////////////////////////////// - -static inline QString msgUnixCallFailedErrno(const char *func, int errorNumber) -{ - return QString::fromLatin1("Call to %1() failed: %2").arg(QLatin1String(func), QString::fromLocal8Bit(strerror(errorNumber))); -} - -class UnixReaderThread : public ReaderThreadBase { - Q_OBJECT - Q_DISABLE_COPY(UnixReaderThread) -public: - explicit UnixReaderThread(const QSharedPointer<DeviceContext> &context); - ~UnixReaderThread(); - - virtual void run(); - -signals: - void error(const QString &); - -public slots: - void terminate(); - -private: - inline int tryRead(); - - int m_terminatePipeFileDescriptors[2]; -}; - -UnixReaderThread::UnixReaderThread(const QSharedPointer<DeviceContext> &context) : - ReaderThreadBase(context) -{ - m_terminatePipeFileDescriptors[0] = m_terminatePipeFileDescriptors[1] = -1; - // Set up pipes for termination. Should not fail - if (pipe(m_terminatePipeFileDescriptors) < 0) - qWarning("%s\n", qPrintable(msgUnixCallFailedErrno("pipe", errno))); -} - -UnixReaderThread::~UnixReaderThread() -{ - close(m_terminatePipeFileDescriptors[0]); - close(m_terminatePipeFileDescriptors[1]); -} - -int UnixReaderThread::tryRead() -{ - fd_set readSet, tempReadSet, tempExceptionSet; - struct timeval timeOut; - const int fileDescriptor = m_context->file.handle(); - FD_ZERO(&readSet); - FD_SET(fileDescriptor, &readSet); - FD_SET(m_terminatePipeFileDescriptors[0], &readSet); - const int maxFileDescriptor = qMax(m_terminatePipeFileDescriptors[0], fileDescriptor); - int result = 0; - do { - memcpy(&tempReadSet, &readSet, sizeof(fd_set)); - memcpy(&tempExceptionSet, &readSet, sizeof(fd_set)); - timeOut.tv_sec = 1; - timeOut.tv_usec = 0; - result = select(maxFileDescriptor + 1, &tempReadSet, NULL, &tempExceptionSet, &timeOut); - } while ( result < 0 && errno == EINTR ); - // Timeout? - if (result == 0) - return 0; - // Something wrong? - if (result < 0) { - emit error(msgUnixCallFailedErrno("select", errno)); - return -1; - } - // Did the exception set trigger on the device? - if (FD_ISSET(fileDescriptor,&tempExceptionSet)) { - emit error(QLatin1String("An Exception occurred on the device.")); - return -2; - } - // Check termination pipe. - if (FD_ISSET(m_terminatePipeFileDescriptors[0], &tempReadSet) - || FD_ISSET(m_terminatePipeFileDescriptors[0], &tempExceptionSet)) - return 1; - - // determine number of pending bytes and read - int numBytes; - if (ioctl(fileDescriptor, FIONREAD, &numBytes) < 0) { - emit error(msgUnixCallFailedErrno("ioctl", errno)); - return -1; - } - m_context->mutex.lock(); - const QByteArray data = m_context->file.read(numBytes); - m_context->mutex.unlock(); - processData(data); - return 0; -} - -void UnixReaderThread::run() -{ - // Read loop - while (tryRead() == 0) - ; -} - -void UnixReaderThread::terminate() -{ - // Trigger select() by writing to the pipe - char c = 0; - const int written = write(m_terminatePipeFileDescriptors[1], &c, 1); - Q_UNUSED(written) - wait(); -} - -typedef UnixReaderThread ReaderThread; - -#endif - -/////////////////////////////////////////////////////////////////////// -// -// TrkDevicePrivate -// -/////////////////////////////////////////////////////////////////////// - -struct TrkDevicePrivate -{ - TrkDevicePrivate(); - - QSharedPointer<DeviceContext> deviceContext; - QScopedPointer<WriterThread> writerThread; - QScopedPointer<ReaderThread> readerThread; - - QByteArray trkReadBuffer; - int verbose; - QString errorString; - QString port; -}; - -/////////////////////////////////////////////////////////////////////// -// -// TrkDevice -// -/////////////////////////////////////////////////////////////////////// - -TrkDevicePrivate::TrkDevicePrivate() : - deviceContext(new DeviceContext), - verbose(0) -{ -} - -/////////////////////////////////////////////////////////////////////// -// -// TrkDevice -// -/////////////////////////////////////////////////////////////////////// - -TrkDevice::TrkDevice(QObject *parent) : - QObject(parent), - d(new TrkDevicePrivate) -{} - -TrkDevice::~TrkDevice() -{ - close(); - delete d; -} - -bool TrkDevice::open(QString *errorMessage) -{ - if (d->verbose || verboseTrk) - qDebug() << "Opening" << port() << "is open: " << isOpen() << " serialFrame=" << serialFrame(); - if (isOpen()) - return true; - if (d->port.isEmpty()) { - *errorMessage = QLatin1String("Internal error: No port set on TrkDevice"); - return false; - } -#ifdef Q_OS_WIN - const QString fullPort = QLatin1String("\\\\.\\") + d->port; - d->deviceContext->device = CreateFile(reinterpret_cast<const WCHAR*>(fullPort.utf16()), - GENERIC_READ | GENERIC_WRITE, - 0, - NULL, - OPEN_EXISTING, - FILE_ATTRIBUTE_NORMAL|FILE_FLAG_NO_BUFFERING|FILE_FLAG_OVERLAPPED, - NULL); - - if (INVALID_HANDLE_VALUE == d->deviceContext->device) { - *errorMessage = QString::fromLatin1("Could not open device '%1': %2").arg(port(), winErrorMessage(GetLastError())); - return false; - } - memset(&d->deviceContext->readOverlapped, 0, sizeof(OVERLAPPED)); - d->deviceContext->readOverlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); - memset(&d->deviceContext->writeOverlapped, 0, sizeof(OVERLAPPED)); - d->deviceContext->writeOverlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); - if (d->deviceContext->readOverlapped.hEvent == NULL || d->deviceContext->writeOverlapped.hEvent == NULL) { - *errorMessage = QString::fromLatin1("Failed to create events: %1").arg(winErrorMessage(GetLastError())); - return false; - } -#else - d->deviceContext->file.setFileName(d->port); - if (!d->deviceContext->file.open(QIODevice::ReadWrite|QIODevice::Unbuffered)) { - *errorMessage = QString::fromLatin1("Cannot open %1: %2").arg(d->port, d->deviceContext->file.errorString()); - return false; - } - - struct termios termInfo; - if (tcgetattr(d->deviceContext->file.handle(), &termInfo) < 0) { - *errorMessage = QString::fromLatin1("Unable to retrieve terminal settings: %1 %2").arg(errno).arg(QString::fromLatin1(strerror(errno))); - return false; - } - // Turn off terminal echo as not get messages back, among other things - termInfo.c_cflag |= CREAD|CLOCAL; - termInfo.c_lflag &= (~(ICANON|ECHO|ECHOE|ECHOK|ECHONL|ISIG)); - termInfo.c_iflag &= (~(INPCK|IGNPAR|PARMRK|ISTRIP|ICRNL|IXANY)); - termInfo.c_oflag &= (~OPOST); - termInfo.c_cc[VMIN] = 0; - termInfo.c_cc[VINTR] = _POSIX_VDISABLE; - termInfo.c_cc[VQUIT] = _POSIX_VDISABLE; - termInfo.c_cc[VSTART] = _POSIX_VDISABLE; - termInfo.c_cc[VSTOP] = _POSIX_VDISABLE; - termInfo.c_cc[VSUSP] = _POSIX_VDISABLE; - if (tcsetattr(d->deviceContext->file.handle(), TCSAFLUSH, &termInfo) < 0) { - *errorMessage = QString::fromLatin1("Unable to apply terminal settings: %1 %2").arg(errno).arg(QString::fromLatin1(strerror(errno))); - return false; - } -#endif - d->readerThread.reset(new ReaderThread(d->deviceContext)); - connect(d->readerThread.data(), SIGNAL(error(QString)), this, SLOT(emitError(QString)), - Qt::QueuedConnection); - connect(d->readerThread.data(), SIGNAL(messageReceived(trk::TrkResult,QByteArray)), - this, SLOT(slotMessageReceived(trk::TrkResult,QByteArray)), - Qt::QueuedConnection); - d->readerThread->start(); - - d->writerThread.reset(new WriterThread(d->deviceContext)); - connect(d->writerThread.data(), SIGNAL(error(QString)), this, SLOT(emitError(QString)), - Qt::QueuedConnection); - d->writerThread->start(); - - if (d->verbose || verboseTrk) - qDebug() << "Opened" << d->port << d->readerThread.data() << d->writerThread.data(); - return true; -} - -void TrkDevice::close() -{ - if (verboseTrk) - qDebug() << "close" << d->port << " is open: " << isOpen() - << " read pending " << (d->readerThread.isNull() ? 0 : d->readerThread->bytesPending()) - << sender(); - if (!isOpen()) - return; - if (d->readerThread) - d->readerThread->terminate(); - if (d->writerThread) - d->writerThread->terminate(); -#ifdef Q_OS_WIN - CloseHandle(d->deviceContext->device); - d->deviceContext->device = INVALID_HANDLE_VALUE; - CloseHandle(d->deviceContext->readOverlapped.hEvent); - CloseHandle(d->deviceContext->writeOverlapped.hEvent); - d->deviceContext->readOverlapped.hEvent = d->deviceContext->writeOverlapped.hEvent = NULL; -#else - d->deviceContext->file.close(); -#endif - - if (d->verbose) - emitLogMessage("Close"); -} - -bool TrkDevice::isOpen() const -{ -#ifdef Q_OS_WIN - return d->deviceContext->device != INVALID_HANDLE_VALUE; -#else - return d->deviceContext->file.isOpen(); -#endif -} - -QString TrkDevice::port() const -{ - return d->port; -} - -void TrkDevice::setPort(const QString &p) -{ - if (verboseTrk) - qDebug() << "setPort" << p; - d->port = p; -} - -QString TrkDevice::errorString() const -{ - return d->errorString; -} - -bool TrkDevice::serialFrame() const -{ - return d->deviceContext->serialFrame; -} - -void TrkDevice::setSerialFrame(bool f) -{ - if (verboseTrk) - qDebug() << "setSerialFrame" << f; - d->deviceContext->serialFrame = f; -} - -int TrkDevice::verbose() const -{ - return d->verbose; -} - -void TrkDevice::setVerbose(int b) -{ - d->verbose = b; -} - -void TrkDevice::slotMessageReceived(const trk::TrkResult &result, const QByteArray &rawData) -{ - if (isOpen()) { // Might receive bytes after closing due to queued connections. - d->writerThread->slotHandleResult(result); - if (d->verbose > 1) - qDebug() << "Received: " << result.toString(); - emit messageReceived(result); - if (!rawData.isEmpty()) - emit rawDataReceived(rawData); - } -} - -void TrkDevice::emitError(const QString &s) -{ - d->errorString = s; - qWarning("%s\n", qPrintable(s)); - emit error(s); -} - -void TrkDevice::clearWriteQueue() -{ - if (isOpen()) - d->writerThread->clearWriteQueue(); -} - -void TrkDevice::sendTrkMessage(byte code, TrkCallback callback, - const QByteArray &data, const QVariant &cookie) -{ - if (!isOpen()) { - emitError(msgAccessingClosedDevice(d->port)); - return; - } - if (!d->writerThread.isNull()) { - if (d->verbose > 1) { - QByteArray msg = "Sending: 0x"; - msg += QByteArray::number(code, 16); - msg += ": "; - msg += stringFromArray(data).toLatin1(); - if (cookie.isValid()) - msg += " Cookie: " + cookie.toString().toLatin1(); - qDebug("%s", msg.data()); - } - d->writerThread->queueTrkMessage(code, callback, data, cookie); - } -} - -void TrkDevice::sendTrkInitialPing() -{ - if (!isOpen()) { - emitError(msgAccessingClosedDevice(d->port)); - return; - } - if (!d->writerThread.isNull()) - d->writerThread->queueTrkInitialPing(); -} - -bool TrkDevice::sendTrkAck(byte token) -{ - if (!isOpen()) { - emitError(msgAccessingClosedDevice(d->port)); - return false; - } - if (d->writerThread.isNull()) - return false; - // The acknowledgement must not be queued! - TrkMessage msg(0x80, token); - msg.token = token; - msg.data.append('\0'); - if (verboseTrk) - qDebug() << "Write synchroneous message: " << msg; - return d->writerThread->trkWriteRawMessage(msg); - // 01 90 00 07 7e 80 01 00 7d 5e 7e -} - -void TrkDevice::emitLogMessage(const QString &msg) -{ - if (d->verbose) - qDebug("%s\n", qPrintable(msg)); - emit logMessage(msg); -} - -} // namespace trk - -#include "trkdevice.moc" diff --git a/src/runonphone/symbianutils/trkdevice.h b/src/runonphone/symbianutils/trkdevice.h deleted file mode 100644 index 38634c72f..000000000 --- a/src/runonphone/symbianutils/trkdevice.h +++ /dev/null @@ -1,143 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the tools applications of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef TRKDEVICE_H -#define TRKDEVICE_H - -#include "symbianutils_global.h" -#include "callback.h" - -#include <QtCore/QObject> -#include <QtCore/QVariant> -#include <QtCore/QByteArray> -#include <QtCore/QSharedPointer> - -QT_BEGIN_NAMESPACE -class QIODevice; -QT_END_NAMESPACE - -namespace trk { - -struct TrkResult; -struct TrkMessage; -struct TrkDevicePrivate; - -/* TrkDevice: Implements a Windows COM or Linux device for - * Trk communications. Provides synchronous write and asynchronous - * read operation. - * The serialFrames property specifies whether packets are encapsulated in - * "0x90 <length>" frames, which is currently the case for serial ports. - * Contains a write message queue allowing - * for queueing messages with a notification callback. If the message receives - * an ACK, the callback is invoked. - * The special message TRK_WRITE_QUEUE_NOOP_CODE code can be used for synchronization. - * The respective message will not be sent, the callback is just invoked. - * Note that calling open/close in quick succession can cause crashes - * due to the use of queused signals. */ - -enum { TRK_WRITE_QUEUE_NOOP_CODE = 0x7f }; - -typedef trk::Callback<const TrkResult &> TrkCallback; - -class SYMBIANUTILS_EXPORT TrkDevice : public QObject -{ - Q_OBJECT - Q_PROPERTY(bool serialFrame READ serialFrame WRITE setSerialFrame) - Q_PROPERTY(bool verbose READ verbose WRITE setVerbose) - Q_PROPERTY(QString port READ port WRITE setPort) -public: - explicit TrkDevice(QObject *parent = 0); - virtual ~TrkDevice(); - - bool open(QString *errorMessage); - bool isOpen() const; - - QString port() const; - void setPort(const QString &p); - - QString errorString() const; - - bool serialFrame() const; - void setSerialFrame(bool f); - - int verbose() const; - void setVerbose(int b); - - // Enqueue a message with a notification callback. - void sendTrkMessage(unsigned char code, - TrkCallback callBack = TrkCallback(), - const QByteArray &data = QByteArray(), - const QVariant &cookie = QVariant()); - - // Enqeue an initial ping - void sendTrkInitialPing(); - - // Send an Ack synchronously, bypassing the queue - bool sendTrkAck(unsigned char token); - -public slots: - void clearWriteQueue(); - -signals: - void messageReceived(const trk::TrkResult &result); - // Emitted with the contents of messages enclosed in 07e, not for log output - void rawDataReceived(const QByteArray &data); - void error(const QString &msg); - void logMessage(const QString &msg); - -private slots: - void slotMessageReceived(const trk::TrkResult &result, const QByteArray &a); - -protected slots: - void emitError(const QString &msg); - void emitLogMessage(const QString &msg); - -public slots: - void close(); - -private: - void readMessages(); - TrkDevicePrivate *d; -}; - -} // namespace trk - -#endif // TRKDEVICE_H diff --git a/src/runonphone/symbianutils/trkutils.cpp b/src/runonphone/symbianutils/trkutils.cpp deleted file mode 100644 index 16b52f35d..000000000 --- a/src/runonphone/symbianutils/trkutils.cpp +++ /dev/null @@ -1,603 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the tools applications of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "trkutils.h" -#include <ctype.h> - -#include <QtCore/QCoreApplication> -#include <QtCore/QDebug> -#include <QtCore/QDate> -#include <QtCore/QDateTime> -#include <QtCore/QTime> - -#define logMessage(s) do { qDebug() << "TRKCLIENT: " << s; } while (0) - -namespace trk { - -Library::Library() : codeseg(0), dataseg(0), pid(0) -{ -} - -Library::Library(const TrkResult &result) : codeseg(0), dataseg(0), pid(0) -{ - if (result.data.size() < 20) { - qWarning("Invalid trk creation notification received."); - return; - } - - const char *data = result.data.constData(); - pid = extractInt(data + 2); - codeseg = extractInt(data + 10); - dataseg = extractInt(data + 14); - const uint len = extractShort(data + 18); - name = result.data.mid(20, len); -} - -TrkAppVersion::TrkAppVersion() -{ - reset(); -} - -void TrkAppVersion::reset() -{ - trkMajor = trkMinor= protocolMajor = protocolMinor = 0; -} - -Session::Session() -{ - reset(); -} - -void Session::reset() -{ - cpuMajor = 0; - cpuMinor = 0; - bigEndian = 0; - defaultTypeSize = 0; - fpTypeSize = 0; - extended1TypeSize = 0; - extended2TypeSize = 0; - pid = 0; - mainTid = 0; - tid = 0; - codeseg = 0; - dataseg = 0; - - libraries.clear(); - trkAppVersion.reset(); -} - -static QString formatCpu(int major, int minor) -{ - //: CPU description of an S60 device - //: %1 major verison, %2 minor version - //: %3 real name of major verison, %4 real name of minor version - const QString str = QCoreApplication::translate("trk::Session", "CPU: v%1.%2%3%4"); - QString majorStr; - QString minorStr; - switch (major) { - case 0x04: - majorStr = " ARM"; - break; - } - switch (minor) { - case 0x00: - minorStr = " 920T"; - break; - } - return str.arg(major).arg(minor).arg(majorStr).arg(minorStr); - } - -QString formatTrkVersion(const TrkAppVersion &version) -{ - QString str = QCoreApplication::translate("trk::Session", - "App TRK: v%1.%2 TRK protocol: v%3.%4"); - str = str.arg(version.trkMajor).arg(version.trkMinor); - return str.arg(version.protocolMajor).arg(version.protocolMinor); -} - -QString Session::deviceDescription(unsigned verbose) const -{ - if (!cpuMajor) - return QString(); - - //: s60description - //: description of an S60 device - //: %1 CPU description, %2 endianness - //: %3 default type size (if any), %4 float size (if any) - //: %5 TRK version - QString msg = QCoreApplication::translate("trk::Session", "%1, %2%3%4, %5"); - QString endianness = bigEndian - ? QCoreApplication::translate("trk::Session", "big endian") - : QCoreApplication::translate("trk::Session", "little endian"); - msg = msg.arg(formatCpu(cpuMajor, cpuMinor)).arg(endianness); - //: The separator in a list of strings - QString defaultTypeSizeStr; - QString fpTypeSizeStr; - if (verbose && defaultTypeSize) - //: will be inserted into s60description - defaultTypeSizeStr = QCoreApplication::translate("trk::Session", ", type size: %1").arg(defaultTypeSize); - if (verbose && fpTypeSize) - //: will be inserted into s60description - fpTypeSizeStr = QCoreApplication::translate("trk::Session", ", float size: %1").arg(fpTypeSize); - msg = msg.arg(defaultTypeSizeStr).arg(fpTypeSizeStr); - return msg.arg(formatTrkVersion(trkAppVersion)); -} - -QByteArray Session::gdbLibraryList() const -{ - const int count = libraries.size(); - QByteArray response = "l<library-list>"; - for (int i = 0; i != count; ++i) { - const trk::Library &lib = libraries.at(i); - response += "<library name=\""; - response += lib.name; - response += "\">"; - response += "<section address=\"0x"; - response += trk::hexNumber(lib.codeseg); - response += "\"/>"; - response += "<section address=\"0x"; - response += trk::hexNumber(lib.dataseg); - response += "\"/>"; - response += "<section address=\"0x"; - response += trk::hexNumber(lib.dataseg); - response += "\"/>"; - response += "</library>"; - } - response += "</library-list>"; - return response; -} - -QByteArray Session::gdbQsDllInfo(int start, int count) const -{ - // Happens with gdb 6.4.50.20060226-cvs / CodeSourcery. - // Never made it into FSF gdb that got qXfer:libraries:read instead. - // http://sourceware.org/ml/gdb/2007-05/msg00038.html - // Name=hexname,TextSeg=textaddr[,DataSeg=dataaddr] - const int libraryCount = libraries.size(); - const int end = count < 0 ? libraryCount : qMin(libraryCount, start + count); - QByteArray response(1, end == libraryCount ? 'l' : 'm'); - for (int i = start; i < end; ++i) { - if (i != start) - response += ';'; - const Library &lib = libraries.at(i); - response += "Name="; - response += lib.name.toHex(); - response += ",TextSeg="; - response += hexNumber(lib.codeseg); - response += ",DataSeg="; - response += hexNumber(lib.dataseg); - } - return response; -} - -QString Session::toString() const -{ - QString rc; - QTextStream str(&rc); - str << "Session: " << deviceDescription(false) << '\n' - << "pid: " << pid << "main thread: " << mainTid - << " current thread: " << tid << ' '; - str.setIntegerBase(16); - str << " code: 0x" << codeseg << " data: 0x" << dataseg << '\n'; - if (const int libCount = libraries.size()) { - str << "Libraries:\n"; - for (int i = 0; i < libCount; i++) - str << " #" << i << ' ' << libraries.at(i).name - << " code: 0x" << libraries.at(i).codeseg - << " data: 0x" << libraries.at(i).dataseg << '\n'; - } - if (const int moduleCount = modules.size()) { - str << "Modules:\n"; - for (int i = 0; i < moduleCount; i++) - str << " #" << i << ' ' << modules.at(i) << '\n'; - } - str.setIntegerBase(10); - if (!addressToBP.isEmpty()) { - typedef QHash<uint, uint>::const_iterator BP_ConstIterator; - str << "Breakpoints:\n"; - const BP_ConstIterator cend = addressToBP.constEnd(); - for (BP_ConstIterator it = addressToBP.constBegin(); it != cend; ++it) { - str.setIntegerBase(16); - str << " 0x" << it.key(); - str.setIntegerBase(10); - str << ' ' << it.value() << '\n'; - } - } - - return rc; -} - -// -------------- - -QByteArray decode7d(const QByteArray &ba) -{ - QByteArray res; - res.reserve(ba.size()); - for (int i = 0; i < ba.size(); ++i) { - byte c = byte(ba.at(i)); - if (c == 0x7d) { - ++i; - c = 0x20 ^ byte(ba.at(i)); - } - res.append(c); - } - return res; -} - -QByteArray encode7d(const QByteArray &ba) -{ - QByteArray res; - res.reserve(ba.size() + 2); - for (int i = 0; i < ba.size(); ++i) { - byte c = byte(ba.at(i)); - if (c == 0x7e || c == 0x7d) { - res.append(0x7d); - res.append(0x20 ^ c); - } else { - res.append(c); - } - } - return res; -} - -// FIXME: Use the QByteArray based version below? -static inline QString stringFromByte(byte c) -{ - return QString::fromLatin1("%1").arg(c, 2, 16, QChar('0')); -} - -SYMBIANUTILS_EXPORT QString stringFromArray(const QByteArray &ba, int maxLen) -{ - QString str; - QString ascii; - const int size = maxLen == -1 ? ba.size() : qMin(ba.size(), maxLen); - for (int i = 0; i < size; ++i) { - const int c = byte(ba.at(i)); - str += QString::fromLatin1("%1 ").arg(c, 2, 16, QChar('0')); - ascii += QChar(c).isPrint() ? QChar(c) : QChar('.'); - } - if (size != ba.size()) { - str += QLatin1String("..."); - ascii += QLatin1String("..."); - } - return str + QLatin1String(" ") + ascii; -} - -SYMBIANUTILS_EXPORT QByteArray hexNumber(uint n, int digits) -{ - QByteArray ba = QByteArray::number(n, 16); - if (digits == 0 || ba.size() == digits) - return ba; - return QByteArray(digits - ba.size(), '0') + ba; -} - -SYMBIANUTILS_EXPORT QByteArray hexxNumber(uint n, int digits) -{ - return "0x" + hexNumber(n, digits); -} - -TrkResult::TrkResult() : - code(0), - token(0), - isDebugOutput(false) -{ -} - -void TrkResult::clear() -{ - code = token= 0; - isDebugOutput = false; - data.clear(); - cookie = QVariant(); -} - -QString TrkResult::toString() const -{ - QString res = stringFromByte(code); - res += QLatin1String(" ["); - res += stringFromByte(token); - res += QLatin1Char(']'); - res += QLatin1Char(' '); - res += stringFromArray(data); - return res; -} - -QByteArray frameMessage(byte command, byte token, const QByteArray &data, bool serialFrame) -{ - byte s = command + token; - for (int i = 0; i != data.size(); ++i) - s += data.at(i); - byte checksum = 255 - (s & 0xff); - //int x = s + ~s; - //logMessage("check: " << s << checksum << x; - - QByteArray response; - response.reserve(data.size() + 3); - response.append(char(command)); - response.append(char(token)); - response.append(data); - response.append(char(checksum)); - - QByteArray encodedData = encode7d(response); - - QByteArray ba; - ba.reserve(encodedData.size() + 6); - if (serialFrame) { - ba.append(char(0x01)); - ba.append(char(0x90)); - const ushort encodedSize = encodedData.size() + 2; // 2 x 0x7e - appendShort(&ba, encodedSize, BigEndian); - } - ba.append(char(0x7e)); - ba.append(encodedData); - ba.append(char(0x7e)); - - return ba; -} - -/* returns 0 if array doesn't represent a result, -otherwise returns the length of the result data */ -ushort isValidTrkResult(const QByteArray &buffer, bool serialFrame, ushort& mux) -{ - if (serialFrame) { - // Serial protocol with length info - if (buffer.length() < 4) - return 0; - mux = extractShort(buffer.data()); - const ushort len = extractShort(buffer.data() + 2); - return (buffer.size() >= len + 4) ? len : ushort(0); - } - // Frameless protocol without length info - const char delimiter = char(0x7e); - const int firstDelimiterPos = buffer.indexOf(delimiter); - // Regular message delimited by 0x7e..0x7e - if (firstDelimiterPos == 0) { - mux = MuxTrk; - const int endPos = buffer.indexOf(delimiter, firstDelimiterPos + 1); - return endPos != -1 ? endPos + 1 - firstDelimiterPos : 0; - } - // Some ASCII log message up to first delimiter or all - return firstDelimiterPos != -1 ? firstDelimiterPos : buffer.size(); -} - -bool extractResult(QByteArray *buffer, bool serialFrame, TrkResult *result, bool &linkEstablishmentMode, QByteArray *rawData) -{ - result->clear(); - if(rawData) - rawData->clear(); - ushort len = isValidTrkResult(*buffer, serialFrame, result->multiplex); - // handle receiving application output, which is not a regular command - const int delimiterPos = serialFrame ? 4 : 0; - if (linkEstablishmentMode) { - //when "hot connecting" a device, we can receive partial frames. - //this code resyncs by discarding data until a TRK frame is found - while (buffer->length() > delimiterPos - && result->multiplex != MuxTextTrace - && !(result->multiplex == MuxTrk && buffer->at(delimiterPos) == 0x7e)) { - buffer->remove(0,1); - len = isValidTrkResult(*buffer, serialFrame, result->multiplex); - } - } - if (!len) - return false; - if (buffer->at(delimiterPos) != 0x7e) { - result->isDebugOutput = true; - result->data = buffer->mid(delimiterPos, len); - buffer->remove(0, delimiterPos + len); - return true; - } - // FIXME: what happens if the length contains 0xfe? - // Assume for now that it passes unencoded! - const QByteArray data = decode7d(buffer->mid(delimiterPos + 1, len - 2)); - if(rawData) - *rawData = data; - buffer->remove(0, delimiterPos + len); - - byte sum = 0; - for (int i = 0; i < data.size(); ++i) // 3 = 2 * 0xfe + sum - sum += byte(data.at(i)); - if (sum != 0xff) - logMessage("*** CHECKSUM ERROR: " << byte(sum)); - - result->code = data.at(0); - result->token = data.at(1); - result->data = data.mid(2, data.size() - 3); - //logMessage(" REST BUF: " << stringFromArray(*buffer)); - //logMessage(" CURR DATA: " << stringFromArray(data)); - //QByteArray prefix = "READ BUF: "; - //logMessage((prefix + "HEADER: " + stringFromArray(header).toLatin1()).data()); - linkEstablishmentMode = false; //have received a good TRK packet, therefore in sync - return true; -} - -SYMBIANUTILS_EXPORT ushort extractShort(const char *data) -{ - return byte(data[0]) * 256 + byte(data[1]); -} - -SYMBIANUTILS_EXPORT uint extractInt(const char *data) -{ - uint res = byte(data[0]); - res *= 256; res += byte(data[1]); - res *= 256; res += byte(data[2]); - res *= 256; res += byte(data[3]); - return res; -} - -SYMBIANUTILS_EXPORT quint64 extractInt64(const char *data) -{ - quint64 res = byte(data[0]); - res <<= 8; res += byte(data[1]); - res <<= 8; res += byte(data[2]); - res <<= 8; res += byte(data[3]); - res <<= 8; res += byte(data[4]); - res <<= 8; res += byte(data[5]); - res <<= 8; res += byte(data[6]); - res <<= 8; res += byte(data[7]); - return res; -} - -SYMBIANUTILS_EXPORT QString quoteUnprintableLatin1(const QByteArray &ba) -{ - QString res; - char buf[10]; - for (int i = 0, n = ba.size(); i != n; ++i) { - const byte c = ba.at(i); - if (isprint(c)) { - res += c; - } else { - qsnprintf(buf, sizeof(buf) - 1, "\\%x", int(c)); - res += buf; - } - } - return res; -} - -SYMBIANUTILS_EXPORT void appendShort(QByteArray *ba, ushort s, Endianness endian) -{ - if (endian == BigEndian) { - ba->append(s / 256); - ba->append(s % 256); - } else { - ba->append(s % 256); - ba->append(s / 256); - } -} - -SYMBIANUTILS_EXPORT void appendInt(QByteArray *ba, uint i, Endianness endian) -{ - const uchar b3 = i % 256; i /= 256; - const uchar b2 = i % 256; i /= 256; - const uchar b1 = i % 256; i /= 256; - const uchar b0 = i; - ba->reserve(ba->size() + 4); - if (endian == BigEndian) { - ba->append(b0); - ba->append(b1); - ba->append(b2); - ba->append(b3); - } else { - ba->append(b3); - ba->append(b2); - ba->append(b1); - ba->append(b0); - } -} - -void appendString(QByteArray *ba, const QByteArray &str, Endianness endian, bool appendNullTerminator) -{ - const int fullSize = str.size() + (appendNullTerminator ? 1 : 0); - appendShort(ba, fullSize, endian); // count the terminating \0 - ba->append(str); - if (appendNullTerminator) - ba->append('\0'); -} - -void appendDateTime(QByteArray *ba, QDateTime dateTime, Endianness endian) -{ - // convert the QDateTime to UTC and append its representation to QByteArray - // format is the same as in FAT file system - dateTime = dateTime.toUTC(); - const QTime utcTime = dateTime.time(); - const QDate utcDate = dateTime.date(); - uint fatDateTime = (utcTime.hour() << 11 | utcTime.minute() << 5 | utcTime.second()/2) << 16; - fatDateTime |= (utcDate.year()-1980) << 9 | utcDate.month() << 5 | utcDate.day(); - appendInt(ba, fatDateTime, endian); -} - -QByteArray errorMessage(byte code) -{ - switch (code) { - case 0x00: return "No error"; - case 0x01: return "Generic error in CWDS message"; - case 0x02: return "Unexpected packet size in send msg"; - case 0x03: return "Internal error occurred in CWDS"; - case 0x04: return "Escape followed by frame flag"; - case 0x05: return "Bad FCS in packet"; - case 0x06: return "Packet too long"; - case 0x07: return "Sequence ID not expected (gap in sequence)"; - - case 0x10: return "Command not supported"; - case 0x11: return "Command param out of range"; - case 0x12: return "An option was not supported"; - case 0x13: return "Read/write to invalid memory"; - case 0x14: return "Read/write invalid registers"; - case 0x15: return "Exception occurred in CWDS"; - case 0x16: return "Targeted system or thread is running"; - case 0x17: return "Breakpoint resources (HW or SW) exhausted"; - case 0x18: return "Requested breakpoint conflicts with existing one"; - - case 0x20: return "General OS-related error"; - case 0x21: return "Request specified invalid process"; - case 0x22: return "Request specified invalid thread"; - } - return "Unknown error"; -} - -uint swapEndian(uint in) -{ - return (in>>24) | ((in<<8) & 0x00FF0000) | ((in>>8) & 0x0000FF00) | (in<<24); -} - -int TrkResult::errorCode() const -{ - // NAK means always error, else data sized 1 with a non-null element - const bool isNAK = code == 0xff; - if (data.size() != 1 && !isNAK) - return 0; - if (const int errorCode = data.at(0)) - return errorCode; - return isNAK ? 0xff : 0; -} - -QString TrkResult::errorString() const -{ - // NAK means always error, else data sized 1 with a non-null element - if (code == 0xff) - return "NAK"; - if (data.size() < 1) - return "Unknown error packet"; - return errorMessage(data.at(0)); -} - -} // namespace trk - diff --git a/src/runonphone/symbianutils/trkutils.h b/src/runonphone/symbianutils/trkutils.h deleted file mode 100644 index f21886878..000000000 --- a/src/runonphone/symbianutils/trkutils.h +++ /dev/null @@ -1,261 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the tools applications of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef DEBUGGER_TRK_UTILS -#define DEBUGGER_TRK_UTILS - -#include "symbianutils_global.h" - -#include <QtCore/QByteArray> -#include <QtCore/QHash> -#include <QtCore/QStringList> -#include <QtCore/QVariant> - -QT_BEGIN_NAMESPACE -class QDateTime; -QT_END_NAMESPACE - -namespace trk { - -typedef unsigned char byte; -struct TrkResult; - -enum Command { - //meta commands - TrkPing = 0x00, - TrkConnect = 0x01, - TrkDisconnect = 0x02, - TrkReset = 0x03, - TrkVersions = 0x04, - TrkSupported = 0x05, - TrkCpuType = 0x06, - TrkConfigTransport = 0x07, - TrkVersions2 = 0x08, - TrkHostVersions = 0x09, - - //state commands - TrkReadMemory = 0x10, - TrkWriteMemory = 0x11, - TrkReadRegisters = 0x12, - TrkWriteRegisters = 0x13, - TrkFillMemory = 0x14, - TrkCopyMemory = 0x15, - TrkFlushCache = 0x16, - - //execution commands - TrkContinue = 0x18, - TrkStep = 0x19, - TrkStop = 0x1a, - TrkSetBreak = 0x1b, - TrkClearBreak = 0x1c, - TrkDownload = 0x1d, - TrkModifyBreakThread = 0x1e, - - //host -> target IO management - TrkNotifyFileInput = 0x20, - TrkBlockFileIo = 0x21, - - //host -> target os commands - TrkCreateItem = 0x40, - TrkDeleteItem = 0x41, - TrkReadInfo = 0x42, - TrkWriteInfo = 0x43, - - TrkWriteFile = 0x48, - TrkReadFile = 0x49, - TrkOpenFile = 0x4a, - TrkCloseFile = 0x4b, - TrkPositionFile = 0x4c, - TrkInstallFile = 0x4d, - TrkInstallFile2 = 0x4e, - - TrkPhoneSwVersion = 0x4f, - TrkPhoneName = 0x50, - TrkVersions3 = 0x51, - - //replies - TrkNotifyAck = 0x80, - TrkNotifyNak = 0xff, - - //target -> host notification - TrkNotifyStopped = 0x90, - TrkNotifyException = 0x91, - TrkNotifyInternalError = 0x92, - TrkNotifyStopped2 = 0x94, - - //target -> host OS notification - TrkNotifyCreated = 0xa0, - TrkNotifyDeleted = 0xa1, - TrkNotifyProcessorStarted = 0xa2, - TrkNotifyProcessorStandBy = 0xa6, - TrkNotifyProcessorReset = 0xa7, - - //target -> host support commands (these are defined but not implemented in TRK) - TrkDSWriteFile = 0xd0, - TrkDSReadFile = 0xd1, - TrkDSOpenFile = 0xd2, - TrkDSCloseFile = 0xd3, - TrkDSPositionFile = 0xd4 -}; - -enum DSOSItemTypes { - kDSOSProcessItem = 0x0000, - kDSOSThreadItem = 0x0001, - kDSOSDLLItem = 0x0002, - kDSOSAppItem = 0x0003, - kDSOSMemBlockItem = 0x0004, - kDSOSProcAttachItem = 0x0005, - kDSOSThreadAttachItem = 0x0006, - kDSOSProcAttach2Item = 0x0007, - kDSOSProcRunItem = 0x0008, - /* 0x0009 - 0x00ff reserved for general expansion */ - /* 0x0100 - 0xffff available for target-specific use */ -}; - -enum SerialMultiplexor { - MuxRaw = 0, - MuxTextTrace = 0x0102, - MuxTrk = 0x0190 -}; - -inline byte extractByte(const char *data) { return *data; } -SYMBIANUTILS_EXPORT ushort extractShort(const char *data); -SYMBIANUTILS_EXPORT uint extractInt(const char *data); -SYMBIANUTILS_EXPORT quint64 extractInt64(const char *data); - -SYMBIANUTILS_EXPORT QString quoteUnprintableLatin1(const QByteArray &ba); - -// produces "xx xx xx " -SYMBIANUTILS_EXPORT QString stringFromArray(const QByteArray &ba, int maxLen = - 1); - -enum Endianness -{ - LittleEndian, - BigEndian, - TargetByteOrder = BigEndian, -}; - -SYMBIANUTILS_EXPORT void appendShort(QByteArray *ba, ushort s, Endianness = TargetByteOrder); -SYMBIANUTILS_EXPORT void appendInt(QByteArray *ba, uint i, Endianness = TargetByteOrder); -SYMBIANUTILS_EXPORT void appendString(QByteArray *ba, const QByteArray &str, Endianness = TargetByteOrder, bool appendNullTerminator = true); - -struct SYMBIANUTILS_EXPORT Library -{ - Library(); - explicit Library(const TrkResult &r); - - QByteArray name; - uint codeseg; - uint dataseg; - //library addresses are valid for a given process (depending on memory model, they might be loaded at the same address in all processes or not) - uint pid; -}; - -struct SYMBIANUTILS_EXPORT TrkAppVersion -{ - TrkAppVersion(); - void reset(); - - int trkMajor; - int trkMinor; - int protocolMajor; - int protocolMinor; -}; - -struct SYMBIANUTILS_EXPORT Session -{ - Session(); - void reset(); - QString deviceDescription(unsigned verbose) const; - QString toString() const; - // Answer to qXfer::libraries - QByteArray gdbLibraryList() const; - // Answer to qsDllInfo, can be sent chunk-wise. - QByteArray gdbQsDllInfo(int start = 0, int count = -1) const; - - // Trk feedback - byte cpuMajor; - byte cpuMinor; - byte bigEndian; - byte defaultTypeSize; - byte fpTypeSize; - byte extended1TypeSize; - byte extended2TypeSize; - TrkAppVersion trkAppVersion; - uint pid; - uint mainTid; - uint tid; - uint codeseg; - uint dataseg; - QHash<uint, uint> addressToBP; - - typedef QList<Library> Libraries; - Libraries libraries; - - // Gdb request - QStringList modules; -}; - -struct SYMBIANUTILS_EXPORT TrkResult -{ - TrkResult(); - void clear(); - QString toString() const; - // 0 for no error. - int errorCode() const; - QString errorString() const; - - ushort multiplex; - byte code; - byte token; - QByteArray data; - QVariant cookie; - bool isDebugOutput; -}; - -SYMBIANUTILS_EXPORT QByteArray errorMessage(byte code); -SYMBIANUTILS_EXPORT QByteArray hexNumber(uint n, int digits = 0); -SYMBIANUTILS_EXPORT QByteArray hexxNumber(uint n, int digits = 0); // prepends '0x', too -SYMBIANUTILS_EXPORT uint swapEndian(uint in); - -} // namespace trk - -#endif // DEBUGGER_TRK_UTILS diff --git a/src/runonphone/symbianutils/trkutils_p.h b/src/runonphone/symbianutils/trkutils_p.h deleted file mode 100644 index 9406caec1..000000000 --- a/src/runonphone/symbianutils/trkutils_p.h +++ /dev/null @@ -1,62 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the tools applications of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef DEBUGGER_TRK_PRIVATE_UTILS -#define DEBUGGER_TRK_PRIVATE_UTILS - -#include "trkutils.h" -#include "symbianutils_global.h" - -QT_BEGIN_NAMESPACE -class QDateTime; -QT_END_NAMESPACE - -namespace trk { - -void appendDateTime(QByteArray *ba, QDateTime dateTime, Endianness = TargetByteOrder); -// returns a QByteArray containing optionally -// the serial frame [0x01 0x90 <len>] and 0x7e encoded7d(ba) 0x7e -QByteArray frameMessage(byte command, byte token, const QByteArray &data, bool serialFrame); -bool extractResult(QByteArray *buffer, bool serialFrame, TrkResult *r, bool& linkEstablishmentMode, QByteArray *rawData = 0); - -} // namespace trk - -#endif // DEBUGGER_TRK_PRIVATE_UTILS diff --git a/src/runonphone/trksignalhandler.cpp b/src/runonphone/trksignalhandler.cpp deleted file mode 100644 index f06fd48c2..000000000 --- a/src/runonphone/trksignalhandler.cpp +++ /dev/null @@ -1,368 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the tools applications of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <QDebug> -#include <QCoreApplication> -#include <QObject> -#include <QFile> -#include <QDir> -#include "trksignalhandler.h" -#include "trkutils.h" - -class CrashState -{ -public: - uint pid; - uint tid; - QString crashReason; - uint crashPC; -}; - -class TrkSignalHandlerPrivate -{ - friend class TrkSignalHandler; -public: - TrkSignalHandlerPrivate(); - ~TrkSignalHandlerPrivate(); -private: - QTextStream out; - QTextStream err; - int loglevel; - int lastpercent; - QList<trk::Library> libraries; - QFile crashlogtextfile; - QFile crashstackfile; - QList<CrashState> queuedCrashes; - QList<int> dyingThreads; - QString crashlogPath; - bool crashlog; - bool terminateNeeded; -}; - -void TrkSignalHandler::copyingStarted() -{ - if (d->loglevel > 0) - d->out << "Copying..." << endl; -} - -void TrkSignalHandler::canNotConnect(const QString &errorMessage) -{ - d->err << "Cannot connect - " << errorMessage << endl; -} - -void TrkSignalHandler::canNotCreateFile(const QString &filename, const QString &errorMessage) -{ - d->err << "Cannot create file (" << filename << ") - " << errorMessage << endl; -} - -void TrkSignalHandler::canNotWriteFile(const QString &filename, const QString &errorMessage) -{ - d->err << "Cannot write file (" << filename << ") - " << errorMessage << endl; -} - -void TrkSignalHandler::canNotCloseFile(const QString &filename, const QString &errorMessage) -{ - d->err << "Cannot close file (" << filename << ") - " << errorMessage << endl; -} - -void TrkSignalHandler::installingStarted() -{ - if (d->loglevel > 0) - d->out << "Installing..." << endl; -} - -void TrkSignalHandler::canNotInstall(const QString &packageFilename, const QString &errorMessage) -{ - d->err << "Cannot install file (" << packageFilename << ") - " << errorMessage << endl; -} - -void TrkSignalHandler::installingFinished() -{ - if (d->loglevel > 0) - d->out << "Installing finished" << endl; -} - -void TrkSignalHandler::startingApplication() -{ - if (d->loglevel > 0) - d->out << "Starting app..." << endl; -} - -void TrkSignalHandler::applicationRunning(uint pid) -{ - Q_UNUSED(pid) - if (d->loglevel > 0) - d->out << "Running..." << endl; -} - -void TrkSignalHandler::canNotRun(const QString &errorMessage) -{ - d->err << "Cannot run - " << errorMessage << endl; -} - -void TrkSignalHandler::finished() -{ - if (d->loglevel > 0) - d->out << "Done." << endl; - QCoreApplication::quit(); -} - -void TrkSignalHandler::applicationOutputReceived(const QString &output) -{ - d->out << output << flush; -} - -void TrkSignalHandler::copyProgress(int percent) -{ - if (d->loglevel > 0) { - if (d->lastpercent == 0) - d->out << "[ ]\r[" << flush; - while (percent > d->lastpercent) { - d->out << QLatin1Char('#'); - d->lastpercent+=2; //because typical console is 80 chars wide - } - d->out.flush(); - if (percent==100) - d->out << endl; - } -} - -void TrkSignalHandler::stateChanged(int state) -{ - if (d->loglevel > 1) - d->out << "State" << state << endl; -} - -void TrkSignalHandler::setLogLevel(int level) -{ - d->loglevel = level; -} - -void TrkSignalHandler::setCrashLogging(bool enabled) -{ - d->crashlog = enabled; -} - -void TrkSignalHandler::setCrashLogPath(QString path) -{ - d->crashlogPath = path; -} - -bool lessThanCodeBase(const trk::Library& cs1, const trk::Library& cs2) -{ - return cs1.codeseg < cs2.codeseg; -} - -void TrkSignalHandler::stopped(uint pc, uint pid, uint tid, const QString& reason) -{ - d->err << "STOPPED: pc=" << hex << pc << " pid=" << pid - << " tid=" << tid << dec << " - " << reason << endl; - - if (d->crashlog) { - CrashState cs; - cs.pid = pid; - cs.tid = tid; - cs.crashPC = pc; - cs.crashReason = reason; - - if (d->dyingThreads.contains(tid)) { - if(d->queuedCrashes.isEmpty()) - emit terminate(); - else - d->terminateNeeded = true; - } else { - d->queuedCrashes.append(cs); - d->dyingThreads.append(tid); - - if (d->queuedCrashes.count() == 1) { - d->err << "Fetching registers and stack..." << endl; - emit getRegistersAndCallStack(pid, tid); - } - } - } - else - emit terminate(); -} - -void TrkSignalHandler::registersAndCallStackReadComplete(const QList<uint>& registers, const QByteArray& stack) -{ - CrashState cs = d->queuedCrashes.first(); - QDir dir(d->crashlogPath); - d->crashlogtextfile.setFileName(dir.filePath(QString("d_exc_%1.txt").arg(cs.tid))); - d->crashstackfile.setFileName(dir.filePath(QString("d_exc_%1.stk").arg(cs.tid))); - d->crashlogtextfile.open(QIODevice::WriteOnly); - QTextStream crashlog(&d->crashlogtextfile); - - crashlog << "-----------------------------------------------------------------------------" << endl; - crashlog << "EKA2 USER CRASH LOG" << endl; - crashlog << "Thread Name: " << QString("ProcessID-%1::ThreadID-%2").arg(cs.pid).arg(cs.tid) << endl; - crashlog << "Thread ID: " << cs.tid << endl; - //this is wrong, but TRK doesn't make stack limit available so we lie - crashlog << QString("User Stack %1-%2").arg(registers.at(13), 8, 16, QChar('0')).arg(registers.at(13) + stack.size(), 8, 16, QChar('0')) << endl; - //this is also wrong, but TRK doesn't give all information for exceptions - crashlog << QString("Panic: PC=%1 ").arg(cs.crashPC, 8, 16, QChar('0')) << cs.crashReason << endl; - crashlog << endl; - crashlog << "USER REGISTERS:" << endl; - crashlog << QString("CPSR=%1").arg(registers.at(16), 8, 16, QChar('0')) << endl; - for (int i=0;i<16;i+=4) { - crashlog << QString("r%1=%2 %3 %4 %5") - .arg(i, 2, 10, QChar('0')) - .arg(registers.at(i), 8, 16, QChar('0')) - .arg(registers.at(i+1), 8, 16, QChar('0')) - .arg(registers.at(i+2), 8, 16, QChar('0')) - .arg(registers.at(i+3), 8, 16, QChar('0')) << endl; - } - crashlog << endl; - - //emit info for post mortem debug - qSort(d->libraries.begin(), d->libraries.end(), lessThanCodeBase); - d->err << "Code Segments:" << endl; - crashlog << "CODE SEGMENTS:" << endl; - for(int i=0; i<d->libraries.count(); i++) { - const trk::Library& seg = d->libraries.at(i); - if(seg.pid != cs.pid) - continue; - if (d->loglevel > 1) { - d->err << QString("Code: %1 Data: %2 Name: ") - .arg(seg.codeseg, 8, 16, QChar('0')) - .arg(seg.dataseg, 8, 16, QChar('0')) - << seg.name << endl; - } - - //produce fake code segment end addresses since we don't get the real ones from TRK - uint end; - if (i+1 < d->libraries.count()) - end = d->libraries.at(i+1).codeseg - 1; - else - end = 0xFFFFFFFF; - - crashlog << QString("%1-%2 ") - .arg(seg.codeseg, 8, 16, QChar('0')) - .arg(end, 8, 16, QChar('0')) - << seg.name << endl; - } - - d->crashlogtextfile.close(); - - if (d->loglevel > 1) { - d->err << "Registers:" << endl; - for (int i=0;i<16;i++) { - d->err << QString("R%1: %2 ").arg(i, 2, 10, QChar('0')).arg(registers.at(i), 8, 16, QChar('0')); - if (i % 4 == 3) - d->err << endl; - } - d->err << QString("CPSR: %1").arg(registers.at(16), 8, 16, QChar('0')) << endl; - - d->err << "Stack:" << endl; - uint sp = registers.at(13); - for(int i=0; i<stack.size(); i+=16, sp+=16) { - d->err << QString("%1: ").arg(sp, 8, 16, QChar('0')); - d->err << trk::stringFromArray(stack.mid(i,16)); - d->err << endl; - } - } - d->crashstackfile.open(QIODevice::WriteOnly); - d->crashstackfile.write(stack); - d->crashstackfile.close(); - - if (d->loglevel > 0) - d->err << "Crash logs saved to " << d->crashlogtextfile.fileName() << " & " << d->crashstackfile.fileName() << endl; - - // resume the thread to allow Symbian OS to handle the panic normally. - // terminate when a non main thread is suspended reboots the phone (TRK bug) - emit resume(cs.pid, cs.tid); - - //fetch next crashed thread - d->queuedCrashes.removeFirst(); - if (d->queuedCrashes.count()) { - cs = d->queuedCrashes.first(); - d->err << "Fetching registers and stack..." << endl; - emit getRegistersAndCallStack(cs.pid, cs.tid); - } - else if (d->terminateNeeded) - emit terminate(); - -} - -void TrkSignalHandler::libraryLoaded(const trk::Library &lib) -{ - d->libraries << lib; -} - -void TrkSignalHandler::libraryUnloaded(const trk::Library &lib) -{ - for (QList<trk::Library>::iterator i = d->libraries.begin(); i != d->libraries.end(); i++) { - if((*i).name == lib.name && (*i).pid == lib.pid) - i = d->libraries.erase(i); - } -} - -void TrkSignalHandler::timeout() -{ - d->err << "FAILED: stopping test due to timeout" << endl; - emit terminate(); -} - -TrkSignalHandlerPrivate::TrkSignalHandlerPrivate() - : out(stdout), - err(stderr), - loglevel(0), - lastpercent(0), - terminateNeeded(false) -{ - -} - -TrkSignalHandlerPrivate::~TrkSignalHandlerPrivate() -{ - out.flush(); - err.flush(); -} - -TrkSignalHandler::TrkSignalHandler() - : d(new TrkSignalHandlerPrivate()) -{ -} - -TrkSignalHandler::~TrkSignalHandler() -{ - delete d; -} diff --git a/src/runonphone/trksignalhandler.h b/src/runonphone/trksignalhandler.h deleted file mode 100644 index 1b75e707d..000000000 --- a/src/runonphone/trksignalhandler.h +++ /dev/null @@ -1,88 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the tools applications of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef TRKSIGNALHANDLER_H -#define TRKSIGNALHANDLER_H -#include <QObject> -#include <QString> -#include "symbianutils/trkutils.h" - -class TrkSignalHandlerPrivate; -class TrkSignalHandler : public QObject -{ - Q_OBJECT -public slots: - void copyingStarted(); - void canNotConnect(const QString &errorMessage); - void canNotCreateFile(const QString &filename, const QString &errorMessage); - void canNotWriteFile(const QString &filename, const QString &errorMessage); - void canNotCloseFile(const QString &filename, const QString &errorMessage); - void installingStarted(); - void canNotInstall(const QString &packageFilename, const QString &errorMessage); - void installingFinished(); - void startingApplication(); - void applicationRunning(uint pid); - void canNotRun(const QString &errorMessage); - void finished(); - void applicationOutputReceived(const QString &output); - void copyProgress(int percent); - void stateChanged(int); - void stopped(uint pc, uint pid, uint tid, const QString& reason); - void timeout(); - void libraryLoaded(const trk::Library &lib); - void libraryUnloaded(const trk::Library &lib); - void registersAndCallStackReadComplete(const QList<uint>& registers, const QByteArray& stack); -signals: - void resume(uint pid, uint tid); - void stop(uint pid, uint tid); - void terminate(); - void getRegistersAndCallStack(uint pid, uint tid); -public: - TrkSignalHandler(); - ~TrkSignalHandler(); - void setLogLevel(int); - void setCrashLogging(bool); - void setCrashLogPath(QString); -private: - TrkSignalHandlerPrivate *d; -}; - -#endif // TRKSIGNALHANDLER_H |