| 
									
										
										
										
											2010-12-06 13:52:47 +01:00
										 |  |  | /**************************************************************************
 | 
					
						
							|  |  |  | ** | 
					
						
							|  |  |  | ** This file is part of Qt Creator | 
					
						
							|  |  |  | ** | 
					
						
							| 
									
										
										
										
											2012-01-26 18:33:46 +01:00
										 |  |  | ** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies). | 
					
						
							| 
									
										
										
										
											2010-12-06 13:52:47 +01:00
										 |  |  | ** | 
					
						
							| 
									
										
										
										
											2011-11-02 15:59:12 +01:00
										 |  |  | ** Contact: Nokia Corporation (qt-info@nokia.com) | 
					
						
							| 
									
										
										
										
											2010-12-06 13:52:47 +01:00
										 |  |  | ** | 
					
						
							|  |  |  | ** | 
					
						
							|  |  |  | ** GNU Lesser General Public License Usage | 
					
						
							|  |  |  | ** | 
					
						
							| 
									
										
										
										
											2011-04-13 08:42:33 +02:00
										 |  |  | ** This file may be used under the terms of the GNU Lesser General Public | 
					
						
							|  |  |  | ** License version 2.1 as published by the Free Software Foundation and | 
					
						
							|  |  |  | ** appearing in the file LICENSE.LGPL included in the packaging of this file. | 
					
						
							|  |  |  | ** Please review the following information to ensure the GNU Lesser General | 
					
						
							|  |  |  | ** Public License version 2.1 requirements will be met: | 
					
						
							|  |  |  | ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
 | 
					
						
							| 
									
										
										
										
											2010-12-06 13:52:47 +01:00
										 |  |  | ** | 
					
						
							| 
									
										
										
										
											2010-12-17 17:14:20 +01:00
										 |  |  | ** In addition, as a special exception, Nokia gives you certain additional | 
					
						
							| 
									
										
										
										
											2011-04-13 08:42:33 +02:00
										 |  |  | ** rights. These rights are described in the Nokia Qt LGPL Exception | 
					
						
							| 
									
										
										
										
											2010-12-17 17:14:20 +01:00
										 |  |  | ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. | 
					
						
							|  |  |  | ** | 
					
						
							| 
									
										
										
										
											2011-04-13 08:42:33 +02:00
										 |  |  | ** Other Usage | 
					
						
							|  |  |  | ** | 
					
						
							|  |  |  | ** Alternatively, this file may be used in accordance with the terms and | 
					
						
							|  |  |  | ** conditions contained in a signed written agreement between you and Nokia. | 
					
						
							|  |  |  | ** | 
					
						
							| 
									
										
										
										
											2010-12-17 17:14:20 +01:00
										 |  |  | ** If you have questions regarding the use of this file, please contact | 
					
						
							| 
									
										
										
										
											2011-11-02 15:59:12 +01:00
										 |  |  | ** Nokia at qt-info@nokia.com. | 
					
						
							| 
									
										
										
										
											2010-12-06 13:52:47 +01:00
										 |  |  | ** | 
					
						
							|  |  |  | **************************************************************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "codaclientapplication.h"
 | 
					
						
							| 
									
										
										
										
											2011-01-25 09:18:45 +01:00
										 |  |  | #include  "virtualserialdevice.h"
 | 
					
						
							| 
									
										
										
										
											2011-07-19 14:39:00 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-08 16:50:40 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-10 16:48:41 +01:00
										 |  |  | #include "codadevice.h"
 | 
					
						
							| 
									
										
										
										
											2010-12-06 13:52:47 +01:00
										 |  |  | #include <QtNetwork/QTcpSocket>
 | 
					
						
							| 
									
										
										
										
											2010-12-06 17:07:18 +01:00
										 |  |  | #include <QtCore/QFile>
 | 
					
						
							|  |  |  | #include <QtCore/QFileInfo>
 | 
					
						
							| 
									
										
										
										
											2010-12-06 13:52:47 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include <cstdio>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static const char usageC[] = | 
					
						
							| 
									
										
										
										
											2011-11-22 15:50:49 +01:00
										 |  |  | "\n%1 v0.1 built " __DATE__ "\n\n" | 
					
						
							| 
									
										
										
										
											2010-12-06 13:52:47 +01:00
										 |  |  | "Test client for Symbian CODA\n\n" | 
					
						
							|  |  |  | "Usage:\n" | 
					
						
							| 
									
										
										
										
											2010-12-09 09:49:23 +01:00
										 |  |  | "%1 ping            connection   Note: For serial connections ONLY.\n" | 
					
						
							|  |  |  | "%1 launch [-d]     connection binary uid [--] [arguments]\n" | 
					
						
							|  |  |  | "%1 install[-s]     connection remote-sis-file [targetdrive]\n" | 
					
						
							| 
									
										
										
										
											2011-04-15 10:54:41 +02:00
										 |  |  | "%1 uninstall       connection packageUID\n" | 
					
						
							| 
									
										
										
										
											2010-12-09 09:49:23 +01:00
										 |  |  | "%1 put    [c size] connection local-file remote-file\n" | 
					
						
							|  |  |  | "%1 stat            connection remote-file\n\n" | 
					
						
							|  |  |  | "'connection': address[:port] or serial-port\n\n" | 
					
						
							|  |  |  | "Options:\n" | 
					
						
							| 
									
										
										
										
											2010-12-06 17:07:18 +01:00
										 |  |  | "-d            Launch: Launch under Debug control (wait for termination)\n" | 
					
						
							| 
									
										
										
										
											2010-12-07 11:05:25 +01:00
										 |  |  | "-c [size]     Put: Chunk size in KB (default %2KB)\n" | 
					
						
							|  |  |  | "-s            Install: Silent installation\n\n" | 
					
						
							|  |  |  | "Notes:\n" | 
					
						
							|  |  |  | "UIDs take the form '0xfdaa278'. The target directory for sis-files on a\n" | 
					
						
							|  |  |  | "device typically is 'c:\\data'. CODA's default port is %3.\n\n" | 
					
						
							|  |  |  | "Example session:\n" | 
					
						
							|  |  |  | "%1 put     192.168.0.42 test.sis c:\\data\\test.sis\n" | 
					
						
							|  |  |  | "%1 stat    192.168.0.42 c:\\data\\test.sis\n" | 
					
						
							|  |  |  | "%1 install 192.168.0.42 c:\\data\\test.sis c:\n" | 
					
						
							| 
									
										
										
										
											2010-12-09 09:49:23 +01:00
										 |  |  | "%1 launch  192.168.0.42 c:\\sys\\bin\\test.exe  0x34f2b\n" | 
					
						
							|  |  |  | "%1 ping    /dev/ttyUSB1\n"; | 
					
						
							| 
									
										
										
										
											2010-12-06 13:52:47 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | static const unsigned short defaultPort = 65029; | 
					
						
							| 
									
										
										
										
											2010-12-07 11:05:25 +01:00
										 |  |  | static const quint64  defaultChunkSize = 10240; | 
					
						
							| 
									
										
										
										
											2010-12-06 13:52:47 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-09 09:49:23 +01:00
										 |  |  | static inline bool isSerialPort(const QString &address) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return address.startsWith(QLatin1String("/dev")) | 
					
						
							|  |  |  |         || address.startsWith(QLatin1String("com"), Qt::CaseInsensitive) | 
					
						
							|  |  |  |         || address.startsWith(QLatin1String("tty"), Qt::CaseInsensitive) | 
					
						
							|  |  |  |         || address.startsWith(QLatin1Char('\\')); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-06 13:52:47 +01:00
										 |  |  | static inline QString fixSlashes(QString s) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     s.replace(QLatin1Char('/'), QLatin1Char('\\')); | 
					
						
							|  |  |  |     return s; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | CodaClientApplication::CodaClientApplication(int &argc, char **argv) : | 
					
						
							|  |  |  |     QCoreApplication(argc, argv), | 
					
						
							|  |  |  |     m_mode(Invalid), | 
					
						
							|  |  |  |     m_port(defaultPort), | 
					
						
							|  |  |  |     m_launchUID(0), | 
					
						
							|  |  |  |     m_launchDebug(false), | 
					
						
							| 
									
										
										
										
											2011-04-15 10:54:41 +02:00
										 |  |  |     m_uninstallPackage(0), | 
					
						
							| 
									
										
										
										
											2010-12-06 13:52:47 +01:00
										 |  |  |     m_installTargetDrive(QLatin1String("C:")), | 
					
						
							| 
									
										
										
										
											2010-12-06 17:07:18 +01:00
										 |  |  |     m_installSilently(false), | 
					
						
							|  |  |  |     m_putWriteOk(false), | 
					
						
							|  |  |  |     m_statFstatOk(false), | 
					
						
							| 
									
										
										
										
											2010-12-07 11:05:25 +01:00
										 |  |  |     m_putLastChunkSize(0), | 
					
						
							|  |  |  |     m_putChunkSize(defaultChunkSize), | 
					
						
							| 
									
										
										
										
											2010-12-06 13:52:47 +01:00
										 |  |  |     m_verbose(0) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     setApplicationName(QLatin1String("codaclient")); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | CodaClientApplication::~CodaClientApplication() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | QString CodaClientApplication::usage() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return QString::fromLatin1(usageC) | 
					
						
							| 
									
										
										
										
											2010-12-07 11:05:25 +01:00
										 |  |  |             .arg(QCoreApplication::applicationName()) | 
					
						
							|  |  |  |             .arg(defaultChunkSize / 1024).arg(defaultPort); | 
					
						
							| 
									
										
										
										
											2010-12-06 13:52:47 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static inline CodaClientApplication::Mode modeArg(const QString &a) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (a == QLatin1String("launch")) | 
					
						
							|  |  |  |         return CodaClientApplication::Launch; | 
					
						
							| 
									
										
										
										
											2010-12-09 09:49:23 +01:00
										 |  |  |     if (a == QLatin1String("ping")) | 
					
						
							|  |  |  |         return CodaClientApplication::Ping; | 
					
						
							| 
									
										
										
										
											2010-12-06 13:52:47 +01:00
										 |  |  |     if (a == QLatin1String("install")) | 
					
						
							|  |  |  |         return CodaClientApplication::Install; | 
					
						
							| 
									
										
										
										
											2011-04-15 10:54:41 +02:00
										 |  |  |     if (a == QLatin1String("uninstall")) | 
					
						
							|  |  |  |         return CodaClientApplication::Uninstall; | 
					
						
							| 
									
										
										
										
											2010-12-06 17:07:18 +01:00
										 |  |  |     if (a == QLatin1String("put")) | 
					
						
							|  |  |  |         return CodaClientApplication::Put; | 
					
						
							|  |  |  |     if (a == QLatin1String("stat")) | 
					
						
							|  |  |  |         return CodaClientApplication::Stat; | 
					
						
							| 
									
										
										
										
											2010-12-06 13:52:47 +01:00
										 |  |  |     return CodaClientApplication::Invalid; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool CodaClientApplication::parseArgument(const QString &a, int argNumber, QString *errorMessage) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     switch (argNumber) { | 
					
						
							|  |  |  |     case 1: | 
					
						
							|  |  |  |         m_mode = modeArg(a); | 
					
						
							|  |  |  |         if (m_mode == Invalid) { | 
					
						
							|  |  |  |             *errorMessage = QLatin1String("Invalid mode"); | 
					
						
							|  |  |  |             return false; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         return true; | 
					
						
							|  |  |  |     case 2:  { // Address/port
 | 
					
						
							|  |  |  |         m_address = a; | 
					
						
							|  |  |  |         const int colonPos = m_address.indexOf(':'); | 
					
						
							|  |  |  |         if (colonPos != -1) { | 
					
						
							|  |  |  |             m_port = m_address.mid(colonPos + 1).toUInt(); | 
					
						
							|  |  |  |             m_address.truncate(colonPos); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     case 3: | 
					
						
							|  |  |  |         switch (m_mode) { | 
					
						
							|  |  |  |         case Launch: | 
					
						
							|  |  |  |             m_launchBinary = fixSlashes(a); | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |         case Install: | 
					
						
							|  |  |  |             m_installSisFile = a; | 
					
						
							|  |  |  |             break; | 
					
						
							| 
									
										
										
										
											2011-04-15 10:54:41 +02:00
										 |  |  |         case Uninstall: | 
					
						
							|  |  |  |             m_uninstallPackage = a.toUInt(0, 0); | 
					
						
							|  |  |  |             if (!m_uninstallPackage) { | 
					
						
							|  |  |  |                 *errorMessage = QLatin1String("Invalid UID"); | 
					
						
							|  |  |  |                 return false; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             break; | 
					
						
							| 
									
										
										
										
											2010-12-06 17:07:18 +01:00
										 |  |  |         case Put: | 
					
						
							|  |  |  |             m_putLocalFile = a; | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |         case Stat: | 
					
						
							|  |  |  |             m_statRemoteFile = fixSlashes(a); | 
					
						
							| 
									
										
										
										
											2010-12-06 13:52:47 +01:00
										 |  |  |             break; | 
					
						
							|  |  |  |         default: | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         return true; | 
					
						
							|  |  |  |     case 4: | 
					
						
							|  |  |  |         switch (m_mode) { | 
					
						
							|  |  |  |         case Launch: | 
					
						
							|  |  |  |             m_launchUID = a.toUInt(0, 0); | 
					
						
							|  |  |  |             if (!m_launchUID) { | 
					
						
							|  |  |  |                 *errorMessage = QLatin1String("Invalid UID"); | 
					
						
							|  |  |  |                 return false; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |         case Install: | 
					
						
							|  |  |  |             m_installTargetDrive = a; | 
					
						
							|  |  |  |             break; | 
					
						
							| 
									
										
										
										
											2010-12-06 17:07:18 +01:00
										 |  |  |         case Put: | 
					
						
							|  |  |  |             m_putRemoteFile = fixSlashes(a); | 
					
						
							| 
									
										
										
										
											2010-12-06 13:52:47 +01:00
										 |  |  |             break; | 
					
						
							|  |  |  |         default: | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         return true; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     default: | 
					
						
							|  |  |  |         if (m_mode == Launch) | 
					
						
							|  |  |  |             m_launchArgs.push_back(a); | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return true; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | CodaClientApplication::ParseArgsResult CodaClientApplication::parseArguments(QString *errorMessage) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     int argNumber = 1; | 
					
						
							|  |  |  |     const QStringList args = QCoreApplication::arguments(); | 
					
						
							|  |  |  |     const QStringList::const_iterator cend = args.constEnd(); | 
					
						
							|  |  |  |     QStringList::const_iterator it = args.constBegin(); | 
					
						
							|  |  |  |     bool optionsEnd = false; | 
					
						
							|  |  |  |     for (++it; it != cend; ++it) { | 
					
						
							|  |  |  |         if (!optionsEnd  && *it == QLatin1String("--")) { | 
					
						
							|  |  |  |             optionsEnd = true; | 
					
						
							|  |  |  |             continue; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         if (!optionsEnd &&  it->startsWith(QLatin1Char('-')) && it->size() == 2) { | 
					
						
							|  |  |  |             switch (it->at(1).toAscii()) { | 
					
						
							|  |  |  |             case 'v': | 
					
						
							|  |  |  |                 m_verbose++; | 
					
						
							|  |  |  |                 break; | 
					
						
							|  |  |  |             case 'd': | 
					
						
							|  |  |  |                 m_launchDebug = true; | 
					
						
							|  |  |  |                 break; | 
					
						
							| 
									
										
										
										
											2010-12-06 17:07:18 +01:00
										 |  |  |             case 's': | 
					
						
							|  |  |  |                 m_installSilently = true; | 
					
						
							|  |  |  |                 break; | 
					
						
							| 
									
										
										
										
											2010-12-07 11:05:25 +01:00
										 |  |  |             case 'c': | 
					
						
							|  |  |  |                 if (++it == cend) { | 
					
						
							|  |  |  |                     *errorMessage = QString::fromLatin1("Parameter missing for -c"); | 
					
						
							|  |  |  |                     return ParseArgsError; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 m_putChunkSize = it->toULongLong() * 1024; | 
					
						
							|  |  |  |                 if (!m_putChunkSize) { | 
					
						
							|  |  |  |                     *errorMessage = QString::fromLatin1("Invalid chunk size."); | 
					
						
							|  |  |  |                     return ParseArgsError; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 break; | 
					
						
							| 
									
										
										
										
											2010-12-06 13:52:47 +01:00
										 |  |  |             default: | 
					
						
							|  |  |  |                 *errorMessage = QString::fromLatin1("Invalid option %1").arg(*it); | 
					
						
							|  |  |  |                 return ParseArgsError; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |             if (!parseArgument(*it, argNumber++, errorMessage)) | 
					
						
							|  |  |  |                 return ParseArgsError; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } //for loop
 | 
					
						
							|  |  |  |     // Basic Check & init
 | 
					
						
							|  |  |  |     switch (m_mode) { | 
					
						
							|  |  |  |     case Invalid: | 
					
						
							|  |  |  |         return ParseArgsError; | 
					
						
							|  |  |  |     case Launch: | 
					
						
							|  |  |  |         if (m_address.isEmpty() || !m_launchUID || m_launchBinary.isEmpty()) { | 
					
						
							|  |  |  |             *errorMessage = QString::fromLatin1("Not enough parameters for launch."); | 
					
						
							|  |  |  |             return ParseInitError; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         break; | 
					
						
							| 
									
										
										
										
											2010-12-09 09:49:23 +01:00
										 |  |  |     case Ping: | 
					
						
							|  |  |  |         if (m_address.isEmpty()) { | 
					
						
							|  |  |  |             *errorMessage = QString::fromLatin1("Not enough parameters for ping."); | 
					
						
							|  |  |  |             return ParseInitError; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         if (!isSerialPort(m_address)) { | 
					
						
							|  |  |  |             *errorMessage = QString::fromLatin1("'ping' not supported for TCP/IP."); | 
					
						
							|  |  |  |             return ParseInitError; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         break; | 
					
						
							| 
									
										
										
										
											2010-12-06 13:52:47 +01:00
										 |  |  |     case Install: | 
					
						
							|  |  |  |         if (m_address.isEmpty() || m_installSisFile.isEmpty()) { | 
					
						
							|  |  |  |             *errorMessage = QString::fromLatin1("Not enough parameters for install."); | 
					
						
							|  |  |  |             return ParseInitError; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         break; | 
					
						
							| 
									
										
										
										
											2011-04-15 10:54:41 +02:00
										 |  |  |     case Uninstall: | 
					
						
							|  |  |  |         if (!m_uninstallPackage) { | 
					
						
							|  |  |  |             *errorMessage = QString::fromLatin1("Not enough parameters for uninstall."); | 
					
						
							|  |  |  |             return ParseInitError; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         break; | 
					
						
							| 
									
										
										
										
											2010-12-06 17:07:18 +01:00
										 |  |  |     case Put: { | 
					
						
							|  |  |  |         if (m_address.isEmpty() || m_putLocalFile.isEmpty() || m_putRemoteFile.isEmpty()) { | 
					
						
							|  |  |  |             *errorMessage = QString::fromLatin1("Not enough parameters for put."); | 
					
						
							|  |  |  |             return ParseInitError; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         const QFileInfo fi(m_putLocalFile); | 
					
						
							|  |  |  |         if (!fi.isFile() || !fi.isReadable()) { | 
					
						
							|  |  |  |             *errorMessage = QString::fromLatin1("Local file '%1' not readable.").arg(m_putLocalFile); | 
					
						
							| 
									
										
										
										
											2010-12-06 13:52:47 +01:00
										 |  |  |             return ParseInitError; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2010-12-06 17:07:18 +01:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2010-12-06 13:52:47 +01:00
										 |  |  |         break; | 
					
						
							|  |  |  |     default: | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return ParseArgsOk; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool CodaClientApplication::start() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2010-12-07 15:20:09 +01:00
										 |  |  |     m_startTime.start(); | 
					
						
							| 
									
										
										
										
											2010-12-06 13:52:47 +01:00
										 |  |  |     switch (m_mode) { | 
					
						
							| 
									
										
										
										
											2010-12-09 09:49:23 +01:00
										 |  |  |     case Ping: | 
					
						
							|  |  |  |         break; | 
					
						
							| 
									
										
										
										
											2010-12-06 13:52:47 +01:00
										 |  |  |     case Launch: { | 
					
						
							|  |  |  |         const QString args = m_launchArgs.join(QString(QLatin1Char(' '))); | 
					
						
							| 
									
										
										
										
											2010-12-08 16:50:40 +01:00
										 |  |  |         std::printf("Launching 0x%x '%s '%s' (debug: %d)\n", | 
					
						
							| 
									
										
										
										
											2010-12-06 13:52:47 +01:00
										 |  |  |                     m_launchUID, qPrintable(m_launchBinary), | 
					
						
							| 
									
										
										
										
											2010-12-08 16:50:40 +01:00
										 |  |  |                     qPrintable(args), m_launchDebug); | 
					
						
							| 
									
										
										
										
											2010-12-06 13:52:47 +01:00
										 |  |  |     } | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     case Install: | 
					
						
							| 
									
										
										
										
											2010-12-08 16:50:40 +01:00
										 |  |  |         std::printf("Installing '%s' to '%s'\n", | 
					
						
							|  |  |  |                     qPrintable(m_installSisFile), qPrintable(m_installTargetDrive)); | 
					
						
							| 
									
										
										
										
											2010-12-06 13:52:47 +01:00
										 |  |  |         break; | 
					
						
							| 
									
										
										
										
											2011-04-15 10:54:41 +02:00
										 |  |  |     case Uninstall: | 
					
						
							|  |  |  |         std::printf("Uninstalling 0x%x'\n", | 
					
						
							|  |  |  |                     m_uninstallPackage); | 
					
						
							|  |  |  |         break; | 
					
						
							| 
									
										
										
										
											2010-12-06 17:07:18 +01:00
										 |  |  |     case Put: | 
					
						
							| 
									
										
										
										
											2010-12-08 16:50:40 +01:00
										 |  |  |         std::printf("Copying '%s' to '%s' in chunks of %lluKB\n", | 
					
						
							| 
									
										
										
										
											2010-12-06 17:07:18 +01:00
										 |  |  |                     qPrintable(m_putLocalFile), qPrintable(m_putRemoteFile), | 
					
						
							| 
									
										
										
										
											2010-12-08 16:50:40 +01:00
										 |  |  |                     m_putChunkSize / 1024); | 
					
						
							| 
									
										
										
										
											2010-12-06 13:52:47 +01:00
										 |  |  |         break; | 
					
						
							| 
									
										
										
										
											2010-12-06 17:07:18 +01:00
										 |  |  |     case Stat: | 
					
						
							| 
									
										
										
										
											2010-12-08 16:50:40 +01:00
										 |  |  |         std::printf("Retrieving attributes of '%s'\n", qPrintable(m_statRemoteFile)); | 
					
						
							| 
									
										
										
										
											2010-12-06 17:07:18 +01:00
										 |  |  |         break; | 
					
						
							| 
									
										
										
										
											2010-12-06 13:52:47 +01:00
										 |  |  |     case Invalid: | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     // Start connection
 | 
					
						
							| 
									
										
										
										
											2011-02-10 16:48:41 +01:00
										 |  |  |     m_trkDevice.reset(new Coda::CodaDevice); | 
					
						
							| 
									
										
										
										
											2010-12-06 13:52:47 +01:00
										 |  |  |     m_trkDevice->setVerbose(m_verbose); | 
					
						
							|  |  |  |     connect(m_trkDevice.data(), SIGNAL(error(QString)), | 
					
						
							|  |  |  |         this, SLOT(slotError(QString))); | 
					
						
							|  |  |  |     connect(m_trkDevice.data(), SIGNAL(logMessage(QString)), | 
					
						
							|  |  |  |         this, SLOT(slotTrkLogMessage(QString))); | 
					
						
							| 
									
										
										
										
											2011-07-19 14:39:00 +02:00
										 |  |  |     connect(m_trkDevice.data(), SIGNAL(codaEvent(Coda::CodaEvent)), | 
					
						
							| 
									
										
										
										
											2011-02-10 16:48:41 +01:00
										 |  |  |         this, SLOT(slotCodaEvent(Coda::CodaEvent))); | 
					
						
							| 
									
										
										
										
											2010-12-09 09:49:23 +01:00
										 |  |  |     connect(m_trkDevice.data(), SIGNAL(serialPong(QString)), | 
					
						
							|  |  |  |             this, SLOT(slotSerialPong(QString))); | 
					
						
							|  |  |  |     if (isSerialPort(m_address)) { | 
					
						
							| 
									
										
										
										
											2010-12-08 16:50:40 +01:00
										 |  |  |         // Serial
 | 
					
						
							| 
									
										
										
										
											2011-01-25 09:18:45 +01:00
										 |  |  |         const QSharedPointer<QIODevice> serialPort(new SymbianUtils::VirtualSerialDevice(m_address)); | 
					
						
							|  |  |  |         std::printf("Opening port %s...\n", qPrintable(m_address)); | 
					
						
							| 
									
										
										
										
											2010-12-08 16:50:40 +01:00
										 |  |  |         m_trkDevice->setSerialFrame(true); | 
					
						
							|  |  |  |         m_trkDevice->setDevice(serialPort); // Grab all data from start
 | 
					
						
							| 
									
										
										
										
											2011-01-25 09:18:45 +01:00
										 |  |  |         if (!serialPort->open(QIODevice::ReadWrite)) { | 
					
						
							| 
									
										
										
										
											2010-12-08 16:50:40 +01:00
										 |  |  |             std::fprintf(stderr, "Cannot open port: %s", qPrintable(serialPort->errorString())); | 
					
						
							|  |  |  |             return false; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         // Initiate communication
 | 
					
						
							| 
									
										
										
										
											2010-12-09 09:49:23 +01:00
										 |  |  |         m_trkDevice->sendSerialPing(m_mode == Ping); | 
					
						
							| 
									
										
										
										
											2010-12-08 16:50:40 +01:00
										 |  |  |     } else { | 
					
						
							|  |  |  |         // TCP/IP
 | 
					
						
							| 
									
										
										
										
											2011-02-10 16:48:41 +01:00
										 |  |  |         const QSharedPointer<QTcpSocket> codaSocket(new QTcpSocket); | 
					
						
							|  |  |  |         m_trkDevice->setDevice(codaSocket); | 
					
						
							|  |  |  |         codaSocket->connectToHost(m_address, m_port); | 
					
						
							| 
									
										
										
										
											2010-12-08 16:50:40 +01:00
										 |  |  |         std::printf("Connecting to %s:%hu...\n", qPrintable(m_address), m_port); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2010-12-06 13:52:47 +01:00
										 |  |  |     return true; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void CodaClientApplication::slotError(const QString &e) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     std::fprintf(stderr, "Error: %s\n", qPrintable(e)); | 
					
						
							|  |  |  |     doExit(-1); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void CodaClientApplication::slotTrkLogMessage(const QString &m) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2010-12-09 09:49:23 +01:00
										 |  |  |     printTimeStamp(); | 
					
						
							| 
									
										
										
										
											2010-12-06 13:52:47 +01:00
										 |  |  |     std::printf("%s\n", qPrintable(m)); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-10 16:48:41 +01:00
										 |  |  | void CodaClientApplication::handleCreateProcess(const Coda::CodaCommandResult &result) | 
					
						
							| 
									
										
										
										
											2010-12-06 13:52:47 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2011-02-10 16:48:41 +01:00
										 |  |  |     const bool ok = result.type == Coda::CodaCommandResult::SuccessReply; | 
					
						
							| 
									
										
										
										
											2010-12-06 13:52:47 +01:00
										 |  |  |     if (ok) { | 
					
						
							| 
									
										
										
										
											2010-12-09 09:49:23 +01:00
										 |  |  |         printTimeStamp(); | 
					
						
							| 
									
										
										
										
											2010-12-06 13:52:47 +01:00
										 |  |  |         std::printf("Launch succeeded: %s\n", qPrintable(result.toString())); | 
					
						
							|  |  |  |         if (!m_launchDebug) | 
					
						
							|  |  |  |             doExit(0); | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |         std::fprintf(stderr, "Launch failed: %s\n", qPrintable(result.toString())); | 
					
						
							|  |  |  |         doExit(-1); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-10 16:48:41 +01:00
										 |  |  | void CodaClientApplication::handleFileSystemOpen(const Coda::CodaCommandResult &result) | 
					
						
							| 
									
										
										
										
											2010-12-06 17:07:18 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2011-02-10 16:48:41 +01:00
										 |  |  |     if (result.type != Coda::CodaCommandResult::SuccessReply) { | 
					
						
							| 
									
										
										
										
											2010-12-06 17:07:18 +01:00
										 |  |  |         std::fprintf(stderr, "Open remote file failed: %s\n", qPrintable(result.toString())); | 
					
						
							|  |  |  |         doExit(-1); | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (result.values.size() < 1 || result.values.at(0).data().isEmpty()) { | 
					
						
							|  |  |  |         std::fprintf(stderr, "Internal error: No filehandle obtained\n"); | 
					
						
							|  |  |  |         doExit(-1); | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     m_remoteFileHandle = result.values.at(0).data(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (m_mode == Stat) { | 
					
						
							| 
									
										
										
										
											2011-02-10 16:48:41 +01:00
										 |  |  |         m_trkDevice->sendFileSystemFstatCommand(Coda::CodaCallback(this, &CodaClientApplication::handleFileSystemFStat), | 
					
						
							| 
									
										
										
										
											2010-12-06 17:07:18 +01:00
										 |  |  |                                                m_remoteFileHandle); | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     // Put.
 | 
					
						
							| 
									
										
										
										
											2010-12-07 11:05:25 +01:00
										 |  |  |     m_putFile.reset(new QFile(m_putLocalFile)); | 
					
						
							|  |  |  |     if (!m_putFile->open(QIODevice::ReadOnly)) { // Should not fail, was checked before
 | 
					
						
							|  |  |  |         std::fprintf(stderr, "Open local file failed: %s\n", qPrintable(m_putFile->errorString())); | 
					
						
							| 
									
										
										
										
											2010-12-06 17:07:18 +01:00
										 |  |  |         doExit(-1); | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2010-12-07 11:05:25 +01:00
										 |  |  |     putSendNextChunk(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void CodaClientApplication::putSendNextChunk() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     // Read and send off next chunk
 | 
					
						
							|  |  |  |     const quint64 pos = m_putFile->pos(); | 
					
						
							|  |  |  |     const QByteArray data = m_putFile->read(m_putChunkSize); | 
					
						
							|  |  |  |     if (data.isEmpty()) { | 
					
						
							|  |  |  |         m_putWriteOk = true; | 
					
						
							|  |  |  |         closeRemoteFile(); | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |         m_putLastChunkSize = data.size(); | 
					
						
							| 
									
										
										
										
											2010-12-09 09:49:23 +01:00
										 |  |  |         printTimeStamp(); | 
					
						
							| 
									
										
										
										
											2010-12-07 11:05:25 +01:00
										 |  |  |         std::printf("Writing %llu bytes to remote file '%s' at %llu\n", | 
					
						
							|  |  |  |                     m_putLastChunkSize, | 
					
						
							|  |  |  |                     m_remoteFileHandle.constData(), pos); | 
					
						
							| 
									
										
										
										
											2011-02-10 16:48:41 +01:00
										 |  |  |         m_trkDevice->sendFileSystemWriteCommand(Coda::CodaCallback(this, &CodaClientApplication::handleFileSystemWrite), | 
					
						
							| 
									
										
										
										
											2010-12-07 11:05:25 +01:00
										 |  |  |                                                 m_remoteFileHandle, data, unsigned(pos)); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void CodaClientApplication::closeRemoteFile() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2011-02-10 16:48:41 +01:00
										 |  |  |     m_trkDevice->sendFileSystemCloseCommand(Coda::CodaCallback(this, &CodaClientApplication::handleFileSystemClose), | 
					
						
							| 
									
										
										
										
											2010-12-07 11:05:25 +01:00
										 |  |  |                                             m_remoteFileHandle); | 
					
						
							| 
									
										
										
										
											2010-12-06 17:07:18 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-10 16:48:41 +01:00
										 |  |  | void CodaClientApplication::handleFileSystemWrite(const Coda::CodaCommandResult &result) | 
					
						
							| 
									
										
										
										
											2010-12-06 17:07:18 +01:00
										 |  |  | { | 
					
						
							|  |  |  |     // Close remote file even if copy fails
 | 
					
						
							| 
									
										
										
										
											2010-12-07 11:05:25 +01:00
										 |  |  |     m_putWriteOk = result; | 
					
						
							| 
									
										
										
										
											2010-12-06 17:07:18 +01:00
										 |  |  |     if (!m_putWriteOk) | 
					
						
							|  |  |  |         std::fprintf(stderr, "Writing data failed: %s\n", qPrintable(result.toString())); | 
					
						
							| 
									
										
										
										
											2010-12-07 11:05:25 +01:00
										 |  |  |     if (!m_putWriteOk || m_putLastChunkSize < m_putChunkSize) { | 
					
						
							|  |  |  |         closeRemoteFile(); | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |         putSendNextChunk(); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2010-12-06 17:07:18 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-10 16:48:41 +01:00
										 |  |  | void CodaClientApplication::handleFileSystemFStat(const Coda::CodaCommandResult &result) | 
					
						
							| 
									
										
										
										
											2010-12-06 17:07:18 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2011-02-10 16:48:41 +01:00
										 |  |  |     m_statFstatOk = result.type == Coda::CodaCommandResult::SuccessReply; | 
					
						
							| 
									
										
										
										
											2010-12-06 17:07:18 +01:00
										 |  |  |     // Close remote file even if copy fails
 | 
					
						
							|  |  |  |     if (m_statFstatOk) { | 
					
						
							| 
									
										
										
										
											2011-02-10 16:48:41 +01:00
										 |  |  |         const Coda::CodaStatResponse statr = Coda::CodaDevice::parseStat(result); | 
					
						
							| 
									
										
										
										
											2010-12-09 09:49:23 +01:00
										 |  |  |         printTimeStamp(); | 
					
						
							| 
									
										
										
										
											2010-12-06 17:07:18 +01:00
										 |  |  |         std::printf("File: %s\nSize: %llu bytes\nAccessed: %s\nModified: %s\n", | 
					
						
							|  |  |  |                     qPrintable(m_statRemoteFile), statr.size, | 
					
						
							|  |  |  |                     qPrintable(statr.accessTime.toString(Qt::LocalDate)), | 
					
						
							|  |  |  |                     qPrintable(statr.modTime.toString(Qt::LocalDate))); | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |         std::fprintf(stderr, "FStat failed: %s\n", qPrintable(result.toString())); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2010-12-08 16:50:40 +01:00
										 |  |  |     closeRemoteFile(); | 
					
						
							| 
									
										
										
										
											2010-12-06 17:07:18 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-10 16:48:41 +01:00
										 |  |  | void CodaClientApplication::handleFileSystemClose(const Coda::CodaCommandResult &result) | 
					
						
							| 
									
										
										
										
											2010-12-06 17:07:18 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2011-02-10 16:48:41 +01:00
										 |  |  |     if (result.type == Coda::CodaCommandResult::SuccessReply) { | 
					
						
							| 
									
										
										
										
											2010-12-09 09:49:23 +01:00
										 |  |  |         printTimeStamp(); | 
					
						
							| 
									
										
										
										
											2010-12-07 15:20:09 +01:00
										 |  |  |         std::printf("File closed.\n"); | 
					
						
							| 
									
										
										
										
											2010-12-06 17:07:18 +01:00
										 |  |  |         const bool ok = m_mode == Put ? m_putWriteOk : m_statFstatOk; | 
					
						
							|  |  |  |         doExit(ok ? 0 : -1); | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |         std::fprintf(stderr, "File close failed: %s\n", qPrintable(result.toString())); | 
					
						
							|  |  |  |         doExit(-1); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-10 16:48:41 +01:00
										 |  |  | void CodaClientApplication::handleSymbianInstall(const Coda::CodaCommandResult &result) | 
					
						
							| 
									
										
										
										
											2010-12-06 17:07:18 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2011-02-10 16:48:41 +01:00
										 |  |  |     if (result.type == Coda::CodaCommandResult::SuccessReply) { | 
					
						
							| 
									
										
										
										
											2010-12-09 09:49:23 +01:00
										 |  |  |         printTimeStamp(); | 
					
						
							| 
									
										
										
										
											2010-12-06 17:07:18 +01:00
										 |  |  |         std::printf("Installation succeeded\n."); | 
					
						
							|  |  |  |         doExit(0); | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |         std::fprintf(stderr, "Installation failed: %s\n", qPrintable(result.toString())); | 
					
						
							|  |  |  |         doExit(-1); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-04-15 10:54:41 +02:00
										 |  |  | void CodaClientApplication::handleUninstall(const Coda::CodaCommandResult &result) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (result.type == Coda::CodaCommandResult::SuccessReply) { | 
					
						
							|  |  |  |         printTimeStamp(); | 
					
						
							|  |  |  |         std::printf("Uninstallation succeeded\n."); | 
					
						
							|  |  |  |         doExit(0); | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |         std::fprintf(stderr, "Uninstallation failed: %s\n", qPrintable(result.toString())); | 
					
						
							|  |  |  |         doExit(-1); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-10 16:48:41 +01:00
										 |  |  | void CodaClientApplication::slotCodaEvent (const Coda::CodaEvent &ev) | 
					
						
							| 
									
										
										
										
											2010-12-06 13:52:47 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-12-09 09:49:23 +01:00
										 |  |  |     printTimeStamp(); | 
					
						
							| 
									
										
										
										
											2010-12-06 13:52:47 +01:00
										 |  |  |     std::printf("Event: %s\n", qPrintable(ev.toString())); | 
					
						
							|  |  |  |     switch (ev.type()) { | 
					
						
							| 
									
										
										
										
											2011-02-10 16:48:41 +01:00
										 |  |  |     case Coda::CodaEvent::LocatorHello: // Commands accepted now
 | 
					
						
							| 
									
										
										
										
											2010-12-06 13:52:47 +01:00
										 |  |  |         switch (m_mode) { | 
					
						
							| 
									
										
										
										
											2010-12-09 09:49:23 +01:00
										 |  |  |         case Ping: | 
					
						
							|  |  |  |             break; | 
					
						
							| 
									
										
										
										
											2010-12-06 13:52:47 +01:00
										 |  |  |         case Launch: | 
					
						
							| 
									
										
										
										
											2011-02-10 16:48:41 +01:00
										 |  |  |             m_trkDevice->sendProcessStartCommand(Coda::CodaCallback(this, &CodaClientApplication::handleCreateProcess), | 
					
						
							| 
									
										
										
										
											2010-12-06 13:52:47 +01:00
										 |  |  |                                                  m_launchBinary, m_launchUID, m_launchArgs, QString(), m_launchDebug); | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |         case Install: | 
					
						
							| 
									
										
										
										
											2010-12-06 17:07:18 +01:00
										 |  |  |             if (m_installSilently) { | 
					
						
							| 
									
										
										
										
											2011-02-10 16:48:41 +01:00
										 |  |  |                 m_trkDevice->sendSymbianInstallSilentInstallCommand(Coda::CodaCallback(this, &CodaClientApplication::handleSymbianInstall), | 
					
						
							| 
									
										
										
										
											2010-12-06 17:07:18 +01:00
										 |  |  |                                                                     m_installSisFile.toAscii(), m_installTargetDrive.toAscii()); | 
					
						
							|  |  |  |             } else { | 
					
						
							| 
									
										
										
										
											2011-02-10 16:48:41 +01:00
										 |  |  |                 m_trkDevice->sendSymbianInstallUIInstallCommand(Coda::CodaCallback(this, &CodaClientApplication::handleSymbianInstall), | 
					
						
							| 
									
										
										
										
											2010-12-06 17:07:18 +01:00
										 |  |  |                                                                 m_installSisFile.toAscii()); | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2010-12-06 13:52:47 +01:00
										 |  |  |             break; | 
					
						
							| 
									
										
										
										
											2011-04-15 10:54:41 +02:00
										 |  |  |         case Uninstall: | 
					
						
							|  |  |  |             m_trkDevice->sendSymbianUninstallCommand(Coda::CodaCallback(this, &CodaClientApplication::handleUninstall), | 
					
						
							|  |  |  |                                                      m_uninstallPackage); | 
					
						
							|  |  |  |             break; | 
					
						
							| 
									
										
										
										
											2010-12-06 17:07:18 +01:00
										 |  |  |         case Put: { | 
					
						
							|  |  |  |             const unsigned flags = | 
					
						
							| 
									
										
										
										
											2011-02-10 16:48:41 +01:00
										 |  |  |                     Coda::CodaDevice::FileSystem_TCF_O_WRITE | 
					
						
							|  |  |  |                     |Coda::CodaDevice::FileSystem_TCF_O_CREAT | 
					
						
							|  |  |  |                     |Coda::CodaDevice::FileSystem_TCF_O_TRUNC; | 
					
						
							| 
									
										
										
										
											2010-12-06 17:07:18 +01:00
										 |  |  |             m_putWriteOk = false; | 
					
						
							| 
									
										
										
										
											2011-02-10 16:48:41 +01:00
										 |  |  |             m_trkDevice->sendFileSystemOpenCommand(Coda::CodaCallback(this, &CodaClientApplication::handleFileSystemOpen), | 
					
						
							| 
									
										
										
										
											2010-12-06 17:07:18 +01:00
										 |  |  |                                                    m_putRemoteFile.toAscii(), flags); | 
					
						
							| 
									
										
										
										
											2011-04-15 10:54:41 +02:00
										 |  |  |         } | 
					
						
							|  |  |  |         break; | 
					
						
							| 
									
										
										
										
											2010-12-06 17:07:18 +01:00
										 |  |  |         case Stat: { | 
					
						
							| 
									
										
										
										
											2011-02-10 16:48:41 +01:00
										 |  |  |             const unsigned flags = Coda::CodaDevice::FileSystem_TCF_O_READ; | 
					
						
							| 
									
										
										
										
											2010-12-06 17:07:18 +01:00
										 |  |  |             m_statFstatOk = false; | 
					
						
							| 
									
										
										
										
											2011-02-10 16:48:41 +01:00
										 |  |  |             m_trkDevice->sendFileSystemOpenCommand(Coda::CodaCallback(this, &CodaClientApplication::handleFileSystemOpen), | 
					
						
							| 
									
										
										
										
											2010-12-06 17:07:18 +01:00
										 |  |  |                                                    m_statRemoteFile.toAscii(), flags); | 
					
						
							| 
									
										
										
										
											2011-04-15 10:54:41 +02:00
										 |  |  |         } | 
					
						
							|  |  |  |         break; | 
					
						
							| 
									
										
										
										
											2010-12-06 13:52:47 +01:00
										 |  |  |         case Invalid: | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         break; | 
					
						
							| 
									
										
										
										
											2011-02-10 16:48:41 +01:00
										 |  |  |     case Coda::CodaEvent::RunControlModuleLoadSuspended:  { | 
					
						
							| 
									
										
										
										
											2010-12-06 13:52:47 +01:00
										 |  |  |         // Debug mode start: Continue:
 | 
					
						
							| 
									
										
										
										
											2011-02-10 16:48:41 +01:00
										 |  |  |         const Coda::CodaRunControlModuleLoadContextSuspendedEvent &me = | 
					
						
							|  |  |  |                 static_cast<const Coda::CodaRunControlModuleLoadContextSuspendedEvent &>(ev); | 
					
						
							| 
									
										
										
										
											2010-12-06 13:52:47 +01:00
										 |  |  |         if (me.info().requireResume) { | 
					
						
							| 
									
										
										
										
											2010-12-09 09:49:23 +01:00
										 |  |  |             printTimeStamp(); | 
					
						
							| 
									
										
										
										
											2010-12-06 13:52:47 +01:00
										 |  |  |             std::printf("Continuing...\n"); | 
					
						
							| 
									
										
										
										
											2011-02-10 16:48:41 +01:00
										 |  |  |             m_trkDevice->sendRunControlResumeCommand(Coda::CodaCallback(), me.id()); | 
					
						
							| 
									
										
										
										
											2010-12-06 13:52:47 +01:00
										 |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |         break; | 
					
						
							| 
									
										
										
										
											2011-02-10 16:48:41 +01:00
										 |  |  |     case Coda::CodaEvent::RunControlContextRemoved: // App terminated in debug mode
 | 
					
						
							| 
									
										
										
										
											2010-12-06 13:52:47 +01:00
										 |  |  |         doExit(0); | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     default: | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-09 09:49:23 +01:00
										 |  |  | void CodaClientApplication::slotSerialPong(const QString &v) | 
					
						
							| 
									
										
										
										
											2010-12-06 13:52:47 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-12-09 09:49:23 +01:00
										 |  |  |     printTimeStamp(); | 
					
						
							|  |  |  |     std::printf("Pong from '%s'\n", qPrintable(v)); | 
					
						
							|  |  |  |     if (m_mode == Ping) | 
					
						
							|  |  |  |         doExit(0); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2010-12-07 15:20:09 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-09 09:49:23 +01:00
										 |  |  | void CodaClientApplication::doExit(int ex) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2010-12-06 13:52:47 +01:00
										 |  |  |     if (!m_trkDevice.isNull()) { | 
					
						
							|  |  |  |         const QSharedPointer<QIODevice> dev = m_trkDevice->device(); | 
					
						
							| 
									
										
										
										
											2010-12-08 16:50:40 +01:00
										 |  |  |         if (!dev.isNull()) { | 
					
						
							|  |  |  |             if (QAbstractSocket *socket = qobject_cast<QAbstractSocket *>(dev.data())) { | 
					
						
							|  |  |  |                 if (socket->state() == QAbstractSocket::ConnectedState) | 
					
						
							|  |  |  |                     socket->disconnectFromHost(); | 
					
						
							|  |  |  |             } else { | 
					
						
							|  |  |  |                 if (dev->isOpen()) | 
					
						
							|  |  |  |                     dev->close(); | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2010-12-06 13:52:47 +01:00
										 |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2010-12-09 09:49:23 +01:00
										 |  |  |     printTimeStamp(); | 
					
						
							| 
									
										
										
										
											2010-12-06 13:52:47 +01:00
										 |  |  |     std::printf("Exiting (%d)\n", ex); | 
					
						
							|  |  |  |     exit(ex); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2010-12-09 09:49:23 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | void CodaClientApplication::printTimeStamp() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     const int elapsedMS = m_startTime.elapsed(); | 
					
						
							|  |  |  |     const int secs = elapsedMS / 1000; | 
					
						
							|  |  |  |     const int msecs = elapsedMS % 1000; | 
					
						
							|  |  |  |     std::printf("%4d.%03ds: ", secs, msecs); | 
					
						
							|  |  |  | } |