summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorShane Kearns <shane.kearns@accenture.com>2010-04-07 15:37:04 (GMT)
committerShane Kearns <shane.kearns@accenture.com>2010-04-07 16:11:37 (GMT)
commit9718ea936cf497583f5b824706515b9af17a8ac4 (patch)
treec7127c50656b0605f4f875b63dc1a960ed839acf
parent759b05e07092e049b0e87d8451cad3c40a02cf45 (diff)
downloadQt-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.cpp163
-rw-r--r--tools/runonphone/symbianutils/launcher.h8
-rw-r--r--tools/runonphone/symbianutils/trkutils.h53
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;