|
1 /**************************************************************************** |
|
2 ** |
|
3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). |
|
4 ** All rights reserved. |
|
5 ** Contact: Nokia Corporation (qt-info@nokia.com) |
|
6 ** |
|
7 ** This file is part of the tools applications of the Qt Toolkit. |
|
8 ** |
|
9 ** $QT_BEGIN_LICENSE:LGPL$ |
|
10 ** No Commercial Usage |
|
11 ** This file contains pre-release code and may not be distributed. |
|
12 ** You may use this file in accordance with the terms and conditions |
|
13 ** contained in the Technology Preview License Agreement accompanying |
|
14 ** this package. |
|
15 ** |
|
16 ** GNU Lesser General Public License Usage |
|
17 ** Alternatively, this file may be used under the terms of the GNU Lesser |
|
18 ** General Public License version 2.1 as published by the Free Software |
|
19 ** Foundation and appearing in the file LICENSE.LGPL included in the |
|
20 ** packaging of this file. Please review the following information to |
|
21 ** ensure the GNU Lesser General Public License version 2.1 requirements |
|
22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. |
|
23 ** |
|
24 ** In addition, as a special exception, Nokia gives you certain additional |
|
25 ** rights. These rights are described in the Nokia Qt LGPL Exception |
|
26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. |
|
27 ** |
|
28 ** If you have questions regarding the use of this file, please contact |
|
29 ** Nokia at qt-info@nokia.com. |
|
30 ** |
|
31 ** |
|
32 ** |
|
33 ** |
|
34 ** |
|
35 ** |
|
36 ** |
|
37 ** |
|
38 ** $QT_END_LICENSE$ |
|
39 ** |
|
40 ****************************************************************************/ |
|
41 |
|
42 #include "launcher.h" |
|
43 #include "trkutils.h" |
|
44 #include "trkdevice.h" |
|
45 #include "bluetoothlistener.h" |
|
46 |
|
47 #include <QtCore/QTimer> |
|
48 #include <QtCore/QDateTime> |
|
49 #include <QtCore/QVariant> |
|
50 #include <QtCore/QDebug> |
|
51 #include <QtCore/QQueue> |
|
52 #include <QtCore/QFile> |
|
53 #include <QtCore/QScopedPointer> |
|
54 |
|
55 namespace trk { |
|
56 |
|
57 struct LauncherPrivate { |
|
58 struct CopyState { |
|
59 QString sourceFileName; |
|
60 QString destinationFileName; |
|
61 uint copyFileHandle; |
|
62 QScopedPointer<QByteArray> data; |
|
63 int position; |
|
64 }; |
|
65 |
|
66 explicit LauncherPrivate(const TrkDevicePtr &d); |
|
67 |
|
68 TrkDevicePtr m_device; |
|
69 QString m_trkServerName; |
|
70 QByteArray m_trkReadBuffer; |
|
71 Launcher::State m_state; |
|
72 |
|
73 void logMessage(const QString &msg); |
|
74 // Debuggee state |
|
75 Session m_session; // global-ish data (process id, target information) |
|
76 |
|
77 CopyState m_copyState; |
|
78 QString m_fileName; |
|
79 QString m_commandLineArgs; |
|
80 QString m_installFileName; |
|
81 int m_verbose; |
|
82 Launcher::Actions m_startupActions; |
|
83 bool m_closeDevice; |
|
84 }; |
|
85 |
|
86 LauncherPrivate::LauncherPrivate(const TrkDevicePtr &d) : |
|
87 m_device(d), |
|
88 m_state(Launcher::Disconnected), |
|
89 m_verbose(0), |
|
90 m_closeDevice(true) |
|
91 { |
|
92 if (m_device.isNull()) |
|
93 m_device = TrkDevicePtr(new TrkDevice); |
|
94 } |
|
95 |
|
96 Launcher::Launcher(Actions startupActions, |
|
97 const TrkDevicePtr &dev, |
|
98 QObject *parent) : |
|
99 QObject(parent), |
|
100 d(new LauncherPrivate(dev)) |
|
101 { |
|
102 d->m_startupActions = startupActions; |
|
103 connect(d->m_device.data(), SIGNAL(messageReceived(trk::TrkResult)), this, SLOT(handleResult(trk::TrkResult))); |
|
104 connect(this, SIGNAL(finished()), d->m_device.data(), SLOT(close())); |
|
105 } |
|
106 |
|
107 Launcher::~Launcher() |
|
108 { |
|
109 logMessage("Shutting down.\n"); |
|
110 delete d; |
|
111 } |
|
112 |
|
113 Launcher::State Launcher::state() const |
|
114 { |
|
115 return d->m_state; |
|
116 } |
|
117 |
|
118 void Launcher::setState(State s) |
|
119 { |
|
120 if (s != d->m_state) { |
|
121 d->m_state = s; |
|
122 emit stateChanged(s); |
|
123 } |
|
124 } |
|
125 |
|
126 void Launcher::addStartupActions(trk::Launcher::Actions startupActions) |
|
127 { |
|
128 d->m_startupActions = Actions(d->m_startupActions | startupActions); |
|
129 } |
|
130 |
|
131 void Launcher::setTrkServerName(const QString &name) |
|
132 { |
|
133 d->m_trkServerName = name; |
|
134 } |
|
135 |
|
136 QString Launcher::trkServerName() const |
|
137 { |
|
138 return d->m_trkServerName; |
|
139 } |
|
140 |
|
141 TrkDevicePtr Launcher::trkDevice() const |
|
142 { |
|
143 return d->m_device; |
|
144 } |
|
145 |
|
146 void Launcher::setFileName(const QString &name) |
|
147 { |
|
148 d->m_fileName = name; |
|
149 } |
|
150 |
|
151 void Launcher::setCopyFileName(const QString &srcName, const QString &dstName) |
|
152 { |
|
153 d->m_copyState.sourceFileName = srcName; |
|
154 d->m_copyState.destinationFileName = dstName; |
|
155 } |
|
156 |
|
157 void Launcher::setInstallFileName(const QString &name) |
|
158 { |
|
159 d->m_installFileName = name; |
|
160 } |
|
161 |
|
162 void Launcher::setCommandLineArgs(const QString &args) |
|
163 { |
|
164 d->m_commandLineArgs = args; |
|
165 } |
|
166 |
|
167 void Launcher::setSerialFrame(bool b) |
|
168 { |
|
169 d->m_device->setSerialFrame(b); |
|
170 } |
|
171 |
|
172 bool Launcher::serialFrame() const |
|
173 { |
|
174 return d->m_device->serialFrame(); |
|
175 } |
|
176 |
|
177 |
|
178 bool Launcher::closeDevice() const |
|
179 { |
|
180 return d->m_closeDevice; |
|
181 } |
|
182 |
|
183 void Launcher::setCloseDevice(bool c) |
|
184 { |
|
185 d->m_closeDevice = c; |
|
186 } |
|
187 |
|
188 bool Launcher::startServer(QString *errorMessage) |
|
189 { |
|
190 errorMessage->clear(); |
|
191 if (d->m_verbose) { |
|
192 const QString msg = QString::fromLatin1("Port=%1 Executable=%2 Package=%3 Remote Package=%4 Install file=%5") |
|
193 .arg(d->m_trkServerName, d->m_fileName, d->m_copyState.sourceFileName, d->m_copyState.destinationFileName, d->m_installFileName); |
|
194 logMessage(msg); |
|
195 } |
|
196 if (d->m_startupActions & ActionCopy) { |
|
197 if (d->m_copyState.sourceFileName.isEmpty()) { |
|
198 qWarning("No local filename given for copying package."); |
|
199 return false; |
|
200 } else if (d->m_copyState.destinationFileName.isEmpty()) { |
|
201 qWarning("No remote filename given for copying package."); |
|
202 return false; |
|
203 } |
|
204 } |
|
205 if (d->m_startupActions & ActionInstall && d->m_installFileName.isEmpty()) { |
|
206 qWarning("No package name given for installing."); |
|
207 return false; |
|
208 } |
|
209 if (d->m_startupActions & ActionRun && d->m_fileName.isEmpty()) { |
|
210 qWarning("No remote executable given for running."); |
|
211 return false; |
|
212 } |
|
213 if (!d->m_device->isOpen() && !d->m_device->open(d->m_trkServerName, errorMessage)) |
|
214 return false; |
|
215 if (d->m_closeDevice) { |
|
216 connect(this, SIGNAL(finished()), d->m_device.data(), SLOT(close())); |
|
217 } else { |
|
218 disconnect(this, SIGNAL(finished()), d->m_device.data(), 0); |
|
219 } |
|
220 setState(Connecting); |
|
221 // Set up the temporary 'waiting' state if we do not get immediate connection |
|
222 QTimer::singleShot(1000, this, SLOT(slotWaitingForTrk())); |
|
223 d->m_device->sendTrkInitialPing(); |
|
224 d->m_device->sendTrkMessage(TrkDisconnect); // Disconnect, as trk might be still connected |
|
225 d->m_device->sendTrkMessage(TrkSupported, TrkCallback(this, &Launcher::handleSupportMask)); |
|
226 d->m_device->sendTrkMessage(TrkCpuType, TrkCallback(this, &Launcher::handleCpuType)); |
|
227 d->m_device->sendTrkMessage(TrkVersions, TrkCallback(this, &Launcher::handleTrkVersion)); |
|
228 if (d->m_startupActions != ActionPingOnly) |
|
229 d->m_device->sendTrkMessage(TrkConnect, TrkCallback(this, &Launcher::handleConnect)); |
|
230 return true; |
|
231 } |
|
232 |
|
233 void Launcher::slotWaitingForTrk() |
|
234 { |
|
235 // Set temporary state if we are still in connected state |
|
236 if (state() == Connecting) |
|
237 setState(WaitingForTrk); |
|
238 } |
|
239 |
|
240 void Launcher::handleConnect(const TrkResult &result) |
|
241 { |
|
242 if (result.errorCode()) { |
|
243 emit canNotConnect(result.errorString()); |
|
244 return; |
|
245 } |
|
246 setState(Connected); |
|
247 if (d->m_startupActions & ActionCopy) |
|
248 copyFileToRemote(); |
|
249 else if (d->m_startupActions & ActionInstall) |
|
250 installRemotePackageSilently(); |
|
251 else if (d->m_startupActions & ActionRun) |
|
252 startInferiorIfNeeded(); |
|
253 } |
|
254 |
|
255 void Launcher::setVerbose(int v) |
|
256 { |
|
257 d->m_verbose = v; |
|
258 d->m_device->setVerbose(v); |
|
259 } |
|
260 |
|
261 void Launcher::logMessage(const QString &msg) |
|
262 { |
|
263 if (d->m_verbose) |
|
264 qDebug() << "LAUNCHER: " << qPrintable(msg); |
|
265 } |
|
266 |
|
267 void Launcher::terminate() |
|
268 { |
|
269 switch (state()) { |
|
270 case DeviceDescriptionReceived: |
|
271 case Connected: |
|
272 if (d->m_session.pid) { |
|
273 QByteArray ba; |
|
274 appendShort(&ba, 0x0000, TargetByteOrder); |
|
275 appendInt(&ba, d->m_session.pid, TargetByteOrder); |
|
276 d->m_device->sendTrkMessage(TrkDeleteItem, TrkCallback(this, &Launcher::handleRemoteProcessKilled), ba); |
|
277 return; |
|
278 } |
|
279 if (d->m_copyState.copyFileHandle) |
|
280 closeRemoteFile(true); |
|
281 disconnectTrk(); |
|
282 break; |
|
283 case Disconnected: |
|
284 break; |
|
285 case Connecting: |
|
286 case WaitingForTrk: |
|
287 setState(Disconnected); |
|
288 emit finished(); |
|
289 break; |
|
290 } |
|
291 } |
|
292 |
|
293 void Launcher::handleRemoteProcessKilled(const TrkResult &result) |
|
294 { |
|
295 Q_UNUSED(result) |
|
296 disconnectTrk(); |
|
297 } |
|
298 |
|
299 void Launcher::handleResult(const TrkResult &result) |
|
300 { |
|
301 QByteArray prefix = "READ BUF: "; |
|
302 QByteArray str = result.toString().toUtf8(); |
|
303 if (result.isDebugOutput) { // handle application output |
|
304 logMessage("APPLICATION OUTPUT: " + result.data); |
|
305 emit applicationOutputReceived(result.data); |
|
306 return; |
|
307 } |
|
308 switch (result.code) { |
|
309 case TrkNotifyAck: |
|
310 break; |
|
311 case TrkNotifyNak: { // NAK |
|
312 logMessage(prefix + "NAK: " + str); |
|
313 //logMessage(prefix << "TOKEN: " << result.token); |
|
314 logMessage(prefix + "ERROR: " + errorMessage(result.data.at(0))); |
|
315 break; |
|
316 } |
|
317 case TrkNotifyStopped: { // Notified Stopped |
|
318 logMessage(prefix + "NOTE: STOPPED " + str); |
|
319 // 90 01 78 6a 40 40 00 00 07 23 00 00 07 24 00 00 |
|
320 QString reason; |
|
321 if (result.data.size() >= 14) { |
|
322 uint pc = extractInt(result.data.mid(0,4).constData()); |
|
323 uint pid = extractInt(result.data.mid(4,4).constData()); |
|
324 uint tid = extractInt(result.data.mid(8,4).constData()); |
|
325 ushort len = extractShort(result.data.mid(12,2).constData()); |
|
326 if(len > 0) |
|
327 reason = result.data.mid(14, len); |
|
328 emit(stopped(pc, pid, tid, reason)); |
|
329 } else { |
|
330 emit(stopped(0, 0, 0, reason)); |
|
331 } |
|
332 //const char *data = result.data.data(); |
|
333 // uint addr = extractInt(data); //code address: 4 bytes; code base address for the library |
|
334 // uint pid = extractInt(data + 4); // ProcessID: 4 bytes; |
|
335 // uint tid = extractInt(data + 8); // ThreadID: 4 bytes |
|
336 //logMessage(prefix << " ADDR: " << addr << " PID: " << pid << " TID: " << tid); |
|
337 d->m_device->sendTrkAck(result.token); |
|
338 break; |
|
339 } |
|
340 case TrkNotifyException: { // Notify Exception (obsolete) |
|
341 logMessage(prefix + "NOTE: EXCEPTION " + str); |
|
342 d->m_device->sendTrkAck(result.token); |
|
343 break; |
|
344 } |
|
345 case TrkNotifyInternalError: { // |
|
346 logMessage(prefix + "NOTE: INTERNAL ERROR: " + str); |
|
347 d->m_device->sendTrkAck(result.token); |
|
348 break; |
|
349 } |
|
350 |
|
351 // target->host OS notification |
|
352 case TrkNotifyCreated: { // Notify Created |
|
353 /* |
|
354 const char *data = result.data.data(); |
|
355 byte error = result.data.at(0); |
|
356 byte type = result.data.at(1); // type: 1 byte; for dll item, this value is 2. |
|
357 uint pid = extractInt(data + 2); // ProcessID: 4 bytes; |
|
358 uint tid = extractInt(data + 6); //threadID: 4 bytes |
|
359 uint codeseg = extractInt(data + 10); //code address: 4 bytes; code base address for the library |
|
360 uint dataseg = extractInt(data + 14); //data address: 4 bytes; data base address for the library |
|
361 uint len = extractShort(data + 18); //length: 2 bytes; length of the library name string to follow |
|
362 QByteArray name = result.data.mid(20, len); // name: library name |
|
363 |
|
364 logMessage(prefix + "NOTE: LIBRARY LOAD: " + str); |
|
365 logMessage(prefix + "TOKEN: " + result.token); |
|
366 logMessage(prefix + "ERROR: " + int(error)); |
|
367 logMessage(prefix + "TYPE: " + int(type)); |
|
368 logMessage(prefix + "PID: " + pid); |
|
369 logMessage(prefix + "TID: " + tid); |
|
370 logMessage(prefix + "CODE: " + codeseg); |
|
371 logMessage(prefix + "DATA: " + dataseg); |
|
372 logMessage(prefix + "LEN: " + len); |
|
373 logMessage(prefix + "NAME: " + name); |
|
374 */ |
|
375 |
|
376 if (result.data.size() < 10) |
|
377 break; |
|
378 QByteArray ba; |
|
379 ba.append(result.data.mid(2, 8)); |
|
380 d->m_device->sendTrkMessage(TrkContinue, TrkCallback(), ba, "CONTINUE"); |
|
381 //d->m_device->sendTrkAck(result.token) |
|
382 break; |
|
383 } |
|
384 case TrkNotifyDeleted: { // NotifyDeleted |
|
385 const ushort itemType = (unsigned char)result.data.at(1); |
|
386 const ushort len = result.data.size() > 12 ? extractShort(result.data.data() + 10) : ushort(0); |
|
387 const QString name = len ? QString::fromAscii(result.data.mid(12, len)) : QString(); |
|
388 logMessage(QString::fromLatin1("%1 %2 UNLOAD: %3"). |
|
389 arg(QString::fromAscii(prefix)).arg(itemType ? QLatin1String("LIB") : QLatin1String("PROCESS")). |
|
390 arg(name)); |
|
391 d->m_device->sendTrkAck(result.token); |
|
392 if (itemType == 0 // process |
|
393 && result.data.size() >= 10 |
|
394 && d->m_session.pid == extractInt(result.data.data() + 6)) { |
|
395 disconnectTrk(); |
|
396 } |
|
397 break; |
|
398 } |
|
399 case TrkNotifyProcessorStarted: { // NotifyProcessorStarted |
|
400 logMessage(prefix + "NOTE: PROCESSOR STARTED: " + str); |
|
401 d->m_device->sendTrkAck(result.token); |
|
402 break; |
|
403 } |
|
404 case TrkNotifyProcessorStandBy: { // NotifyProcessorStandby |
|
405 logMessage(prefix + "NOTE: PROCESSOR STANDBY: " + str); |
|
406 d->m_device->sendTrkAck(result.token); |
|
407 break; |
|
408 } |
|
409 case TrkNotifyProcessorReset: { // NotifyProcessorReset |
|
410 logMessage(prefix + "NOTE: PROCESSOR RESET: " + str); |
|
411 d->m_device->sendTrkAck(result.token); |
|
412 break; |
|
413 } |
|
414 default: { |
|
415 logMessage(prefix + "INVALID: " + str); |
|
416 break; |
|
417 } |
|
418 } |
|
419 } |
|
420 |
|
421 QString Launcher::deviceDescription(unsigned verbose) const |
|
422 { |
|
423 return d->m_session.deviceDescription(verbose); |
|
424 } |
|
425 |
|
426 void Launcher::handleTrkVersion(const TrkResult &result) |
|
427 { |
|
428 if (result.errorCode() || result.data.size() < 5) { |
|
429 if (d->m_startupActions == ActionPingOnly) { |
|
430 setState(Disconnected); |
|
431 emit finished(); |
|
432 } |
|
433 return; |
|
434 } |
|
435 d->m_session.trkAppVersion.trkMajor = result.data.at(1); |
|
436 d->m_session.trkAppVersion.trkMinor = result.data.at(2); |
|
437 d->m_session.trkAppVersion.protocolMajor = result.data.at(3); |
|
438 d->m_session.trkAppVersion.protocolMinor = result.data.at(4); |
|
439 setState(DeviceDescriptionReceived); |
|
440 // Ping mode: Log & Terminate |
|
441 if (d->m_startupActions == ActionPingOnly) { |
|
442 qWarning("%s", qPrintable(deviceDescription())); |
|
443 setState(Disconnected); |
|
444 emit finished(); |
|
445 } |
|
446 } |
|
447 |
|
448 void Launcher::handleFileCreation(const TrkResult &result) |
|
449 { |
|
450 if (result.errorCode() || result.data.size() < 6) { |
|
451 emit canNotCreateFile(d->m_copyState.destinationFileName, result.errorString()); |
|
452 disconnectTrk(); |
|
453 return; |
|
454 } |
|
455 const char *data = result.data.data(); |
|
456 d->m_copyState.copyFileHandle = extractInt(data + 2); |
|
457 QFile file(d->m_copyState.sourceFileName); |
|
458 file.open(QIODevice::ReadOnly); |
|
459 d->m_copyState.data.reset(new QByteArray(file.readAll())); |
|
460 d->m_copyState.position = 0; |
|
461 file.close(); |
|
462 continueCopying(); |
|
463 } |
|
464 |
|
465 void Launcher::handleCopy(const TrkResult &result) |
|
466 { |
|
467 if (result.errorCode() || result.data.size() < 4) { |
|
468 closeRemoteFile(true); |
|
469 emit canNotWriteFile(d->m_copyState.destinationFileName, result.errorString()); |
|
470 disconnectTrk(); |
|
471 } else { |
|
472 continueCopying(extractShort(result.data.data() + 2)); |
|
473 } |
|
474 } |
|
475 |
|
476 void Launcher::continueCopying(uint lastCopiedBlockSize) |
|
477 { |
|
478 int size = d->m_copyState.data->length(); |
|
479 d->m_copyState.position += lastCopiedBlockSize; |
|
480 if (size == 0) |
|
481 emit copyProgress(100); |
|
482 else { |
|
483 int percent = qMin((d->m_copyState.position*100)/size, 100); |
|
484 emit copyProgress(percent); |
|
485 } |
|
486 if (d->m_copyState.position < size) { |
|
487 QByteArray ba; |
|
488 appendInt(&ba, d->m_copyState.copyFileHandle, TargetByteOrder); |
|
489 appendString(&ba, d->m_copyState.data->mid(d->m_copyState.position, 2048), TargetByteOrder, false); |
|
490 d->m_device->sendTrkMessage(TrkWriteFile, TrkCallback(this, &Launcher::handleCopy), ba); |
|
491 } else { |
|
492 closeRemoteFile(); |
|
493 } |
|
494 } |
|
495 |
|
496 void Launcher::closeRemoteFile(bool failed) |
|
497 { |
|
498 QByteArray ba; |
|
499 appendInt(&ba, d->m_copyState.copyFileHandle, TargetByteOrder); |
|
500 appendDateTime(&ba, QDateTime::currentDateTime(), TargetByteOrder); |
|
501 d->m_device->sendTrkMessage(TrkCloseFile, |
|
502 failed ? TrkCallback() : TrkCallback(this, &Launcher::handleFileCopied), |
|
503 ba); |
|
504 d->m_copyState.data.reset(); |
|
505 d->m_copyState.copyFileHandle = 0; |
|
506 d->m_copyState.position = 0; |
|
507 } |
|
508 |
|
509 void Launcher::handleFileCopied(const TrkResult &result) |
|
510 { |
|
511 if (result.errorCode()) |
|
512 emit canNotCloseFile(d->m_copyState.destinationFileName, result.errorString()); |
|
513 if (d->m_startupActions & ActionInstall) |
|
514 installRemotePackageSilently(); |
|
515 else if (d->m_startupActions & ActionRun) |
|
516 startInferiorIfNeeded(); |
|
517 else |
|
518 disconnectTrk(); |
|
519 } |
|
520 |
|
521 void Launcher::handleCpuType(const TrkResult &result) |
|
522 { |
|
523 logMessage("HANDLE CPU TYPE: " + result.toString()); |
|
524 if(result.errorCode() || result.data.size() < 7) |
|
525 return; |
|
526 //---TRK------------------------------------------------------ |
|
527 // Command: 0x80 Acknowledge |
|
528 // Error: 0x00 |
|
529 // [80 03 00 04 00 00 04 00 00 00] |
|
530 d->m_session.cpuMajor = result.data.at(1); |
|
531 d->m_session.cpuMinor = result.data.at(2); |
|
532 d->m_session.bigEndian = result.data.at(3); |
|
533 d->m_session.defaultTypeSize = result.data.at(4); |
|
534 d->m_session.fpTypeSize = result.data.at(5); |
|
535 d->m_session.extended1TypeSize = result.data.at(6); |
|
536 //d->m_session.extended2TypeSize = result.data[6]; |
|
537 } |
|
538 |
|
539 void Launcher::handleCreateProcess(const TrkResult &result) |
|
540 { |
|
541 if (result.errorCode()) { |
|
542 emit canNotRun(result.errorString()); |
|
543 disconnectTrk(); |
|
544 return; |
|
545 } |
|
546 // 40 00 00] |
|
547 //logMessage(" RESULT: " + result.toString()); |
|
548 // [80 08 00 00 00 01 B5 00 00 01 B6 78 67 40 00 00 40 00 00] |
|
549 const char *data = result.data.data(); |
|
550 d->m_session.pid = extractInt(data + 1); |
|
551 d->m_session.tid = extractInt(data + 5); |
|
552 d->m_session.codeseg = extractInt(data + 9); |
|
553 d->m_session.dataseg = extractInt(data + 13); |
|
554 if (d->m_verbose) { |
|
555 const QString msg = QString::fromLatin1("Process id: %1 Thread id: %2 code: 0x%3 data: 0x%4"). |
|
556 arg(d->m_session.pid).arg(d->m_session.tid).arg(d->m_session.codeseg, 0, 16). |
|
557 arg(d->m_session.dataseg, 0 ,16); |
|
558 logMessage(msg); |
|
559 } |
|
560 emit applicationRunning(d->m_session.pid); |
|
561 QByteArray ba; |
|
562 appendInt(&ba, d->m_session.pid); |
|
563 appendInt(&ba, d->m_session.tid); |
|
564 d->m_device->sendTrkMessage(TrkContinue, TrkCallback(), ba, "CONTINUE"); |
|
565 } |
|
566 |
|
567 void Launcher::handleWaitForFinished(const TrkResult &result) |
|
568 { |
|
569 logMessage(" FINISHED: " + stringFromArray(result.data)); |
|
570 setState(Disconnected); |
|
571 emit finished(); |
|
572 } |
|
573 |
|
574 void Launcher::handleSupportMask(const TrkResult &result) |
|
575 { |
|
576 if (result.errorCode() || result.data.size() < 32) |
|
577 return; |
|
578 const char *data = result.data.data() + 1; |
|
579 |
|
580 QByteArray str; |
|
581 for (int i = 0; i < 32; ++i) { |
|
582 //str.append(" [" + formatByte(data[i]) + "]: "); |
|
583 for (int j = 0; j < 8; ++j) |
|
584 if (data[i] & (1 << j)) |
|
585 str.append(QByteArray::number(i * 8 + j, 16) + " "); |
|
586 } |
|
587 logMessage("SUPPORTED: " + str); |
|
588 } |
|
589 |
|
590 |
|
591 void Launcher::cleanUp() |
|
592 { |
|
593 // |
|
594 //---IDE------------------------------------------------------ |
|
595 // Command: 0x41 Delete Item |
|
596 // Sub Cmd: Delete Process |
|
597 //ProcessID: 0x0000071F (1823) |
|
598 // [41 24 00 00 00 00 07 1F] |
|
599 QByteArray ba; |
|
600 appendByte(&ba, 0x00); |
|
601 appendByte(&ba, 0x00); |
|
602 appendInt(&ba, d->m_session.pid); |
|
603 d->m_device->sendTrkMessage(TrkDeleteItem, TrkCallback(), ba, "Delete process"); |
|
604 |
|
605 //---TRK------------------------------------------------------ |
|
606 // Command: 0x80 Acknowledge |
|
607 // Error: 0x00 |
|
608 // [80 24 00] |
|
609 |
|
610 //---IDE------------------------------------------------------ |
|
611 // Command: 0x1C Clear Break |
|
612 // [1C 25 00 00 00 0A 78 6A 43 40] |
|
613 |
|
614 //---TRK------------------------------------------------------ |
|
615 // Command: 0xA1 Notify Deleted |
|
616 // [A1 09 00 00 00 00 00 00 00 00 07 1F] |
|
617 //---IDE------------------------------------------------------ |
|
618 // Command: 0x80 Acknowledge |
|
619 // Error: 0x00 |
|
620 // [80 09 00] |
|
621 |
|
622 //---TRK------------------------------------------------------ |
|
623 // Command: 0x80 Acknowledge |
|
624 // Error: 0x00 |
|
625 // [80 25 00] |
|
626 |
|
627 //---IDE------------------------------------------------------ |
|
628 // Command: 0x1C Clear Break |
|
629 // [1C 26 00 00 00 0B 78 6A 43 70] |
|
630 //---TRK------------------------------------------------------ |
|
631 // Command: 0x80 Acknowledge |
|
632 // Error: 0x00 |
|
633 // [80 26 00] |
|
634 |
|
635 |
|
636 //---IDE------------------------------------------------------ |
|
637 // Command: 0x02 Disconnect |
|
638 // [02 27] |
|
639 // sendTrkMessage(0x02, TrkCallback(this, &Launcher::handleDisconnect)); |
|
640 //---TRK------------------------------------------------------ |
|
641 // Command: 0x80 Acknowledge |
|
642 // Error: 0x00 |
|
643 } |
|
644 |
|
645 void Launcher::disconnectTrk() |
|
646 { |
|
647 d->m_device->sendTrkMessage(TrkDisconnect, TrkCallback(this, &Launcher::handleWaitForFinished)); |
|
648 } |
|
649 |
|
650 void Launcher::copyFileToRemote() |
|
651 { |
|
652 emit copyingStarted(); |
|
653 QByteArray ba; |
|
654 appendByte(&ba, 0x10); |
|
655 appendString(&ba, d->m_copyState.destinationFileName.toLocal8Bit(), TargetByteOrder, false); |
|
656 d->m_device->sendTrkMessage(TrkOpenFile, TrkCallback(this, &Launcher::handleFileCreation), ba); |
|
657 } |
|
658 |
|
659 void Launcher::installRemotePackageSilently() |
|
660 { |
|
661 emit installingStarted(); |
|
662 QByteArray ba; |
|
663 appendByte(&ba, 'C'); |
|
664 appendString(&ba, d->m_installFileName.toLocal8Bit(), TargetByteOrder, false); |
|
665 d->m_device->sendTrkMessage(TrkInstallFile, TrkCallback(this, &Launcher::handleInstallPackageFinished), ba); |
|
666 } |
|
667 |
|
668 void Launcher::handleInstallPackageFinished(const TrkResult &result) |
|
669 { |
|
670 if (result.errorCode()) { |
|
671 emit canNotInstall(d->m_installFileName, result.errorString()); |
|
672 disconnectTrk(); |
|
673 return; |
|
674 } else { |
|
675 emit installingFinished(); |
|
676 } |
|
677 if (d->m_startupActions & ActionRun) { |
|
678 startInferiorIfNeeded(); |
|
679 } else { |
|
680 disconnectTrk(); |
|
681 } |
|
682 } |
|
683 |
|
684 void Launcher::startInferiorIfNeeded() |
|
685 { |
|
686 emit startingApplication(); |
|
687 if (d->m_session.pid != 0) { |
|
688 logMessage("Process already 'started'"); |
|
689 return; |
|
690 } |
|
691 // It's not started yet |
|
692 QByteArray ba; |
|
693 appendShort(&ba, 0, TargetByteOrder); // create new process |
|
694 appendByte(&ba, 0); // options - currently unused |
|
695 |
|
696 if(d->m_commandLineArgs.isEmpty()) { |
|
697 appendString(&ba, d->m_fileName.toLocal8Bit(), TargetByteOrder); |
|
698 } else { |
|
699 QByteArray ba2; |
|
700 ba2.append(d->m_fileName.toLocal8Bit()); |
|
701 ba2.append('\0'); |
|
702 ba2.append(d->m_commandLineArgs.toLocal8Bit()); |
|
703 appendString(&ba, ba2, TargetByteOrder); |
|
704 } |
|
705 d->m_device->sendTrkMessage(TrkCreateItem, TrkCallback(this, &Launcher::handleCreateProcess), ba); // Create Item |
|
706 } |
|
707 |
|
708 void Launcher::resume(uint pid, uint tid) |
|
709 { |
|
710 QByteArray ba; |
|
711 appendInt(&ba, pid, BigEndian); |
|
712 appendInt(&ba, tid, BigEndian); |
|
713 d->m_device->sendTrkMessage(TrkContinue, TrkCallback(), ba, "CONTINUE"); |
|
714 } |
|
715 } // namespace trk |