Warning: That file was not part of the compilation database. It may have many parsing errors.

1/****************************************************************************
2**
3** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
4** Contact: http://www.qt-project.org/legal
5**
6** This file is part of the tools applications of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and Digia. For licensing terms and
14** conditions see http://qt.digia.com/licensing. For further information
15** use the contact form at http://qt.digia.com/contact-us.
16**
17** GNU Lesser General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU Lesser
19** General Public License version 2.1 as published by the Free Software
20** Foundation and appearing in the file LICENSE.LGPL included in the
21** packaging of this file. Please review the following information to
22** ensure the GNU Lesser General Public License version 2.1 requirements
23** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24**
25** In addition, as a special exception, Digia gives you certain additional
26** rights. These rights are described in the Digia Qt LGPL Exception
27** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28**
29** GNU General Public License Usage
30** Alternatively, this file may be used under the terms of the GNU
31** General Public License version 3.0 as published by the Free Software
32** Foundation and appearing in the file LICENSE.GPL included in the
33** packaging of this file. Please review the following information to
34** ensure the GNU General Public License version 3.0 requirements will be
35** met: http://www.gnu.org/copyleft/gpl.html.
36**
37**
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42#include <QCoreApplication>
43#include <QTextStream>
44#include <QStringList>
45#include <QScopedPointer>
46#include <QTimer>
47#include <QFileInfo>
48#include "symbianutils/codadevice.h"
49#include "symbianutils/trkutils.h"
50#include "symbianutils/trkdevice.h"
51#include "symbianutils/launcher.h"
52#include "symbianutils/symbiandevicemanager.h"
53
54#include "codasignalhandler.h"
55#include "trksignalhandler.h"
56#include "serenum.h"
57#include "ossignalconverter.h"
58
59void printUsage(QTextStream& outstream, QString exeName)
60{
61 outstream << exeName << " [options] [program] [program arguments]" << endl
62 << "-s, --sis <local file> specify sis file to install" << endl
63 << "-p, --portname <COMx> specify COM port to use by device name" << endl
64 << "-f, --portfriendlyname <substring> specify COM port to use by friendly name" << endl
65 << "-t, --timeout <milliseconds> terminate test if timeout occurs" << endl
66 << "-v, --verbose show debugging output" << endl
67 << "-q, --quiet hide progress messages" << endl
68 << "-u, --upload <local file> <remote file> upload file to phone" << endl
69 << "-d, --download <remote file> <local file> copy file from phone to PC after running test" << endl
70 << "-T, --tempfile <remote file> specify temporary sis file name" << endl
71 << "--nocrashlog Don't capture call stack if test crashes" << endl
72 << "--crashlogpath <dir> Path to save crash logs (default=working dir)" << endl
73 << "--coda Use CODA instead of detecting the debug agent" << endl
74 << "--trk Use TRK instead of detecting the debug agent" << endl
75 << endl
76 << "USB COM ports can usually be autodetected, use -p or -f to force a specific port." << endl
77 << "TRK is the default debugging agent, use --coda option when using CODA instead of TRK." << endl
78 << "If using System TRK, it is possible to copy the program directly to sys/bin on the phone." << endl
79 << "-s can be used with both System and Application TRK/CODA to install the program" << endl;
80}
81
82#define CHECK_PARAMETER_EXISTS if(!it.hasNext()) { printUsage(outstream, args[0]); return 1; }
83int main(int argc, char *argv[])
84{
85 QCoreApplication a(argc, argv);
86
87 QString serialPortName;
88 QString serialPortFriendlyName;
89 QString sisFile;
90 QString exeFile;
91 QStringList cmdLine;
92 QStringList args = QCoreApplication::arguments();
93 QTextStream outstream(stdout);
94 QTextStream errstream(stderr);
95 QString uploadLocalFile;
96 QString uploadRemoteFile;
97 QString downloadRemoteFile;
98 QString downloadLocalFile;
99 QString dstName = "c:\\data\\testtemp.sis";
100 int loglevel=1;
101 int timeout=0;
102 bool crashlog = true;
103 enum {AgentUnknown, AgentCoda, AgentTRK} debugAgent = AgentUnknown;
104 QString crashlogpath;
105 QListIterator<QString> it(args);
106 it.next(); //skip name of program
107 while (it.hasNext()) {
108 QString arg = it.next();
109
110 if (arg.startsWith("-")) {
111 if (arg == "--portname" || arg == "-p") {
112 CHECK_PARAMETER_EXISTS
113 serialPortName = it.next();
114 }
115 else if (arg == "--portfriendlyname" || arg == "-f") {
116 CHECK_PARAMETER_EXISTS
117 serialPortFriendlyName = it.next();
118 }
119 else if (arg == "--sis" || arg == "-s") {
120 CHECK_PARAMETER_EXISTS
121 sisFile = it.next();
122 if (!QFileInfo(sisFile).exists()) {
123 errstream << "Sis file (" << sisFile << ") doesn't exist" << endl;
124 return 1;
125 }
126 }
127 else if (arg == "--upload" || arg == "-u") {
128 CHECK_PARAMETER_EXISTS
129 uploadLocalFile = it.next();
130 if (!QFileInfo(uploadLocalFile).exists()) {
131 errstream << "Executable file (" << uploadLocalFile << ") doesn't exist" << endl;
132 return 1;
133 }
134 CHECK_PARAMETER_EXISTS
135 uploadRemoteFile = it.next();
136 }
137 else if (arg == "--download" || arg == "-d") {
138 CHECK_PARAMETER_EXISTS
139 downloadRemoteFile = it.next();
140 CHECK_PARAMETER_EXISTS
141 downloadLocalFile = it.next();
142 QFileInfo downloadInfo(downloadLocalFile);
143 if (downloadInfo.exists() && !downloadInfo.isFile()) {
144 errstream << downloadLocalFile << " is not a file." << endl;
145 return 1;
146 }
147 }
148 else if (arg == "--timeout" || arg == "-t") {
149 CHECK_PARAMETER_EXISTS
150 bool ok;
151 timeout = it.next().toInt(&ok);
152 if (!ok) {
153 errstream << "Timeout must be specified in milliseconds" << endl;
154 return 1;
155 }
156 }
157 else if (arg == "--coda")
158 debugAgent = AgentCoda;
159 else if (arg == "--trk")
160 debugAgent = AgentTRK;
161 else if (arg == "--tempfile" || arg == "-T") {
162 CHECK_PARAMETER_EXISTS
163 dstName = it.next();
164 }
165 else if (arg == "--verbose" || arg == "-v")
166 loglevel=2;
167 else if (arg == "--quiet" || arg == "-q")
168 loglevel=0;
169 else if (arg == "--nocrashlog")
170 crashlog = false;
171 else if (arg == "--crashlogpath") {
172 CHECK_PARAMETER_EXISTS
173 crashlogpath = it.next();
174 }
175 else
176 errstream << "unknown command line option " << arg << endl;
177 } else {
178 exeFile = arg;
179 while(it.hasNext()) {
180 cmdLine.append(it.next());
181 }
182 }
183 }
184
185 if (exeFile.isEmpty() && sisFile.isEmpty() &&
186 (uploadLocalFile.isEmpty() || uploadRemoteFile.isEmpty()) &&
187 (downloadLocalFile.isEmpty() || downloadRemoteFile.isEmpty())) {
188 printUsage(outstream, args[0]);
189 return 1;
190 }
191
192 if (!uploadLocalFile.isEmpty() && (!downloadLocalFile.isEmpty() || !downloadRemoteFile.isEmpty())) {
193 errstream << "Upload option can't be used together with download" << endl;
194 printUsage(outstream, args[0]);
195 return 1;
196 }
197
198 if (serialPortName.isEmpty()) {
199 if (loglevel > 0)
200 outstream << "Detecting serial ports" << endl;
201 foreach (const SerialPortId &id, enumerateSerialPorts(loglevel)) {
202 if (loglevel > 0)
203 outstream << "Port Name: " << id.portName << ", "
204 << "Friendly Name:" << id.friendlyName << endl;
205 if (!id.friendlyName.isEmpty()
206 && serialPortFriendlyName.isEmpty()
207 && (id.friendlyName.contains("symbian", Qt::CaseInsensitive)
208 || id.friendlyName.contains("s60", Qt::CaseInsensitive)
209 || id.friendlyName.contains("nokia", Qt::CaseInsensitive))) {
210 serialPortName = id.portName;
211 break;
212 } else if (!id.friendlyName.isEmpty()
213 && !serialPortFriendlyName.isEmpty()
214 && id.friendlyName.contains(serialPortFriendlyName)) {
215 serialPortName = id.portName;
216 break;
217 }
218 }
219 if (serialPortName.isEmpty()) {
220 errstream << "No phone found, ensure USB cable is connected or specify manually with -p" << endl;
221 return 1;
222 }
223 }
224
225 CodaSignalHandler codaHandler;
226 QScopedPointer<trk::Launcher> launcher;
227 TrkSignalHandler trkHandler;
228 QFileInfo info(exeFile);
229 QFileInfo uploadInfo(uploadLocalFile);
230
231 if (debugAgent == AgentUnknown) {
232 outstream << "detecting debug agent..." << endl;
233 CodaSignalHandler codaDetector;
234 //auto detect agent
235 codaDetector.setSerialPortName(serialPortName);
236 codaDetector.setLogLevel(loglevel);
237 codaDetector.setActionType(ActionPingOnly);
238 codaDetector.setTimeout(1000);
239 if (!codaDetector.run()) {
240 debugAgent = AgentCoda;
241 outstream << " - Coda is found" << endl;
242 } else {
243 debugAgent = AgentTRK;
244 outstream << " - Coda is not found, defaulting to TRK" << endl;
245 }
246 }
247
248 if (debugAgent == AgentCoda) {
249 codaHandler.setSerialPortName(serialPortName);
250 codaHandler.setLogLevel(loglevel);
251
252 if (!sisFile.isEmpty()) {
253 codaHandler.setActionType(ActionCopyInstall);
254 codaHandler.setCopyFileName(sisFile, dstName);
255 }
256 else if (!uploadLocalFile.isEmpty() && uploadInfo.exists()) {
257 codaHandler.setActionType(ActionCopy);
258 codaHandler.setCopyFileName(uploadLocalFile, uploadRemoteFile);
259 }
260 if (!exeFile.isEmpty()) {
261 codaHandler.setActionType(ActionRun);
262 codaHandler.setAppFileName(QString("c:\\sys\\bin\\") + info.fileName());
263 codaHandler.setCommandLineArgs(cmdLine.join(QLatin1String(", ")));
264 }
265 if (!downloadRemoteFile.isEmpty() && !downloadLocalFile.isEmpty()) {
266 codaHandler.setActionType(ActionDownload);
267 codaHandler.setDownloadFileName(downloadRemoteFile, downloadLocalFile);
268 }
269
270 if (loglevel > 0)
271 outstream << "Connecting to target via " << serialPortName << endl;
272
273 if (timeout > 0)
274 codaHandler.setTimeout(timeout);
275
276 QObject::connect(OsSignalConverter::instance(), SIGNAL(terminate()), &codaHandler, SLOT(terminate()), Qt::QueuedConnection);
277 return codaHandler.run();
278
279 } else {
280 launcher.reset(new trk::Launcher(trk::Launcher::ActionPingOnly,
281 SymbianUtils::SymbianDeviceManager::instance()->acquireDevice(serialPortName)));
282 QStringList srcNames, dstNames;
283 if (!sisFile.isEmpty()) {
284 launcher->addStartupActions(trk::Launcher::ActionCopyInstall);
285 srcNames.append(sisFile);
286 dstNames.append(dstName);
287 launcher->setInstallFileNames(QStringList(dstName));
288 }
289 if (!uploadLocalFile.isEmpty() && uploadInfo.exists()) {
290 launcher->addStartupActions(trk::Launcher::ActionCopy);
291 srcNames.append(uploadLocalFile);
292 dstNames.append(uploadRemoteFile);
293 }
294 launcher->setCopyFileNames(srcNames, dstNames);
295 if (!exeFile.isEmpty()) {
296 launcher->addStartupActions(trk::Launcher::ActionRun);
297 launcher->setFileName(QString("c:\\sys\\bin\\") + info.fileName());
298 launcher->setCommandLineArgs(cmdLine.join(QLatin1String(" ")));
299 }
300 if (!downloadRemoteFile.isEmpty() && !downloadLocalFile.isEmpty()) {
301 launcher->addStartupActions(trk::Launcher::ActionDownload);
302 launcher->setDownloadFileName(downloadRemoteFile, downloadLocalFile);
303 }
304 if (loglevel > 0)
305 outstream << "Connecting to target via " << serialPortName << endl;
306 launcher->setTrkServerName(serialPortName);
307
308 if (loglevel > 1)
309 launcher->setVerbose(1);
310
311 trkHandler.setLogLevel(loglevel);
312 trkHandler.setCrashLogging(crashlog);
313 trkHandler.setCrashLogPath(crashlogpath);
314
315 QObject::connect(launcher.data(), SIGNAL(copyingStarted(const QString &)), &trkHandler, SLOT(copyingStarted(const QString &)));
316 QObject::connect(launcher.data(), SIGNAL(canNotConnect(const QString &)), &trkHandler, SLOT(canNotConnect(const QString &)));
317 QObject::connect(launcher.data(), SIGNAL(canNotCreateFile(const QString &, const QString &)), &trkHandler, SLOT(canNotCreateFile(const QString &, const QString &)));
318 QObject::connect(launcher.data(), SIGNAL(canNotWriteFile(const QString &, const QString &)), &trkHandler, SLOT(canNotWriteFile(const QString &, const QString &)));
319 QObject::connect(launcher.data(), SIGNAL(canNotCloseFile(const QString &, const QString &)), &trkHandler, SLOT(canNotCloseFile(const QString &, const QString &)));
320 QObject::connect(launcher.data(), SIGNAL(installingStarted(const QString &)), &trkHandler, SLOT(installingStarted(const QString &)));
321 QObject::connect(launcher.data(), SIGNAL(canNotInstall(const QString &, const QString &)), &trkHandler, SLOT(canNotInstall(const QString &, const QString &)));
322 QObject::connect(launcher.data(), SIGNAL(installingFinished()), &trkHandler, SLOT(installingFinished()));
323 QObject::connect(launcher.data(), SIGNAL(startingApplication()), &trkHandler, SLOT(startingApplication()));
324 QObject::connect(launcher.data(), SIGNAL(applicationRunning(uint)), &trkHandler, SLOT(applicationRunning(uint)));
325 QObject::connect(launcher.data(), SIGNAL(canNotRun(const QString &)), &trkHandler, SLOT(canNotRun(const QString &)));
326 QObject::connect(launcher.data(), SIGNAL(applicationOutputReceived(const QString &)), &trkHandler, SLOT(applicationOutputReceived(const QString &)));
327 QObject::connect(launcher.data(), SIGNAL(copyProgress(int)), &trkHandler, SLOT(copyProgress(int)));
328 QObject::connect(launcher.data(), SIGNAL(stateChanged(int)), &trkHandler, SLOT(stateChanged(int)));
329 QObject::connect(launcher.data(), SIGNAL(processStopped(uint,uint,uint,QString)), &trkHandler, SLOT(stopped(uint,uint,uint,QString)));
330 QObject::connect(launcher.data(), SIGNAL(libraryLoaded(trk::Library)), &trkHandler, SLOT(libraryLoaded(trk::Library)));
331 QObject::connect(launcher.data(), SIGNAL(libraryUnloaded(trk::Library)), &trkHandler, SLOT(libraryUnloaded(trk::Library)));
332 QObject::connect(launcher.data(), SIGNAL(registersAndCallStackReadComplete(const QList<uint> &,const QByteArray &)), &trkHandler, SLOT(registersAndCallStackReadComplete(const QList<uint> &,const QByteArray &)));
333 QObject::connect(&trkHandler, SIGNAL(resume(uint,uint)), launcher.data(), SLOT(resumeProcess(uint,uint)));
334 QObject::connect(&trkHandler, SIGNAL(terminate()), launcher.data(), SLOT(terminate()));
335 QObject::connect(&trkHandler, SIGNAL(getRegistersAndCallStack(uint,uint)), launcher.data(), SLOT(getRegistersAndCallStack(uint,uint)));
336 QObject::connect(launcher.data(), SIGNAL(finished()), &trkHandler, SLOT(finished()));
337
338 QObject::connect(OsSignalConverter::instance(), SIGNAL(terminate()), launcher.data(), SLOT(terminate()), Qt::QueuedConnection);
339
340 QTimer timer;
341 timer.setSingleShot(true);
342 QObject::connect(&timer, SIGNAL(timeout()), &trkHandler, SLOT(timeout()));
343 if (timeout > 0) {
344 timer.start(timeout);
345 }
346
347 QString errorMessage;
348 if (!launcher->startServer(&errorMessage)) {
349 errstream << errorMessage << endl;
350 return 1;
351 }
352 }
353
354 return a.exec();
355}
356
357

Warning: That file was not part of the compilation database. It may have many parsing errors.