source: trunk/tools/runonphone/symbianutils/launcher.cpp@ 769

Last change on this file since 769 was 769, checked in by Dmitry A. Kuminov, 15 years ago

trunk: Merged in qt 4.6.3 sources from branches/vendor/nokia/qt.

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