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 | |
59 | void 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; } |
83 | int 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.