diff options
author | Shane Kearns <shane.kearns@accenture.com> | 2010-04-07 15:37:04 (GMT) |
---|---|---|
committer | Shane Kearns <shane.kearns@accenture.com> | 2010-04-07 16:11:37 (GMT) |
commit | 9718ea936cf497583f5b824706515b9af17a8ac4 (patch) | |
tree | c7127c50656b0605f4f875b63dc1a960ed839acf | |
parent | 759b05e07092e049b0e87d8451cad3c40a02cf45 (diff) | |
download | Qt-9718ea936cf497583f5b824706515b9af17a8ac4.zip Qt-9718ea936cf497583f5b824706515b9af17a8ac4.tar.gz Qt-9718ea936cf497583f5b824706515b9af17a8ac4.tar.bz2 |
Implement download support to TRK Launcher
Use the TRK protocol to copy a file from the phone to PC after
running the executable.
This can be used for example to download a log file containing test
results.
Submitted upstream as commit 9b65c244d7027d78f0b40450961eab68680d6269.
Reviewed-by: Friedemann Kleint
-rw-r--r-- | tools/runonphone/symbianutils/launcher.cpp | 163 | ||||
-rw-r--r-- | tools/runonphone/symbianutils/launcher.h | 8 | ||||
-rw-r--r-- | tools/runonphone/symbianutils/trkutils.h | 53 |
3 files changed, 200 insertions, 24 deletions
diff --git a/tools/runonphone/symbianutils/launcher.cpp b/tools/runonphone/symbianutils/launcher.cpp index 92b494a..fa509e7 100644 --- a/tools/runonphone/symbianutils/launcher.cpp +++ b/tools/runonphone/symbianutils/launcher.cpp @@ -54,6 +54,8 @@ #include <QtCore/QFile> #include <QtCore/QScopedPointer> +#include <cstdio> + namespace trk { struct LauncherPrivate { @@ -62,7 +64,8 @@ struct LauncherPrivate { QString destinationFileName; uint copyFileHandle; QScopedPointer<QByteArray> data; - int position; + qint64 position; + QScopedPointer<QFile> localFile; }; explicit LauncherPrivate(const TrkDevicePtr &d); @@ -76,6 +79,7 @@ struct LauncherPrivate { 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; @@ -158,6 +162,12 @@ void Launcher::setCopyFileName(const QString &srcName, const QString &dstName) 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; @@ -193,10 +203,26 @@ bool Launcher::startServer(QString *errorMessage) { errorMessage->clear(); if (d->m_verbose) { - const QString msg = QString::fromLatin1("Port=%1 Executable=%2 Arguments=%3 Package=%4 Remote Package=%5 Install file=%6") - .arg(trkServerName(), d->m_fileName, - d->m_commandLineArgs.join(QString(QLatin1Char(' '))), - d->m_copyState.sourceFileName, d->m_copyState.destinationFileName, d->m_installFileName); + 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) { @@ -251,6 +277,8 @@ void Launcher::handleConnect(const TrkResult &result) installRemotePackageSilently(); else if (d->m_startupActions & ActionRun) startInferiorIfNeeded(); + else if (d->m_startupActions & ActionDownload) + copyFileFromRemote(); } void Launcher::setVerbose(int v) @@ -416,7 +444,7 @@ void Launcher::handleResult(const TrkResult &result) if (itemType == 0 // process && result.data.size() >= 10 && d->m_session.pid == extractInt(result.data.data() + 6)) { - disconnectTrk(); + copyFileFromRemote(); } break; } @@ -471,23 +499,99 @@ void Launcher::handleTrkVersion(const TrkResult &result) } } +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) { - emit canNotCreateFile(d->m_copyState.destinationFileName, result.errorString()); + 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); - QFile file(d->m_copyState.sourceFileName); - file.open(QIODevice::ReadOnly); - d->m_copyState.data.reset(new QByteArray(file.readAll())); + 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) { @@ -501,13 +605,14 @@ void Launcher::handleCopy(const TrkResult &result) void Launcher::continueCopying(uint lastCopiedBlockSize) { - int size = d->m_copyState.data->length(); + qint64 size = d->m_copyState.data->length(); d->m_copyState.position += lastCopiedBlockSize; if (size == 0) emit copyProgress(100); else { - int percent = qMin((d->m_copyState.position*100)/size, 100); - emit copyProgress(percent); + 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; @@ -540,6 +645,8 @@ void Launcher::handleFileCopied(const TrkResult &result) installRemotePackageSilently(); else if (d->m_startupActions & ActionRun) startInferiorIfNeeded(); + else if (d->m_startupActions & ActionDownload) + copyFileFromRemote(); else disconnectTrk(); } @@ -603,17 +710,18 @@ void Launcher::handleSupportMask(const TrkResult &result) return; const char *data = result.data.data() + 1; - QString str = QLatin1String("SUPPORTED: "); - for (int i = 0; i < 32; ++i) { - //str.append(" [" + formatByte(data[i]) + "]: "); - for (int j = 0; j < 8; ++j) { - if (data[i] & (1 << j)) { - str.append(QString::number(i * 8 + j, 16)); - str.append(QLatin1Char(' ')); + 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); } - logMessage(str); } void Launcher::cleanUp() @@ -677,11 +785,20 @@ void Launcher::copyFileToRemote() { emit copyingStarted(); QByteArray ba; - ba.append(char(10)); + 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(); @@ -702,6 +819,8 @@ void Launcher::handleInstallPackageFinished(const TrkResult &result) } if (d->m_startupActions & ActionRun) { startInferiorIfNeeded(); + } else if (d->m_startupActions & ActionDownload) { + copyFileFromRemote(); } else { disconnectTrk(); } diff --git a/tools/runonphone/symbianutils/launcher.h b/tools/runonphone/symbianutils/launcher.h index c47285c..6db69d0 100644 --- a/tools/runonphone/symbianutils/launcher.h +++ b/tools/runonphone/symbianutils/launcher.h @@ -69,6 +69,7 @@ public: ActionInstall = 0x2, ActionCopyInstall = ActionCopy | ActionInstall, ActionRun = 0x4, + ActionDownload = 0x8, ActionCopyRun = ActionCopy | ActionRun, ActionInstallRun = ActionInstall | ActionRun, ActionCopyInstallRun = ActionCopy | ActionInstall | ActionRun @@ -94,6 +95,7 @@ public: 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); @@ -132,6 +134,8 @@ signals: 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(); @@ -164,8 +168,11 @@ private: 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); @@ -177,6 +184,7 @@ private: void handleTrkVersion(const TrkResult &result); void copyFileToRemote(); + void copyFileFromRemote(); void installRemotePackageSilently(); void startInferiorIfNeeded(); void handleFinished(); diff --git a/tools/runonphone/symbianutils/trkutils.h b/tools/runonphone/symbianutils/trkutils.h index 3a485c7..553fc7d 100644 --- a/tools/runonphone/symbianutils/trkutils.h +++ b/tools/runonphone/symbianutils/trkutils.h @@ -43,6 +43,7 @@ #define DEBUGGER_TRK_UTILS #include "symbianutils_global.h" + #include <QtCore/QByteArray> #include <QtCore/QHash> #include <QtCore/QStringList> @@ -57,33 +58,81 @@ namespace trk { typedef unsigned char byte; 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 + TrkNotifyProcessorReset = 0xa7, + + //target -> host support commands (these are defined but not implemented in TRK) + TrkDSWriteFile = 0xd0, + TrkDSReadFile = 0xd1, + TrkDSOpenFile = 0xd2, + TrkDSCloseFile = 0xd3, + TrkDSPositionFile = 0xd4 }; inline byte extractByte(const char *data) { return *data; } @@ -118,7 +167,7 @@ struct SYMBIANUTILS_EXPORT Library struct SYMBIANUTILS_EXPORT TrkAppVersion { TrkAppVersion(); - void reset(); + void reset(); int trkMajor; int trkMinor; |