/**************************************************************************** ** ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the tools applications of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** GNU Lesser General Public License Usage ** 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. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** GNU General Public License Usage ** Alternatively, this file may be used under the terms of the GNU General ** Public License version 3.0 as published by the Free Software Foundation ** and appearing in the file LICENSE.GPL included in the packaging of this ** file. Please review the following information to ensure the GNU General ** Public License version 3.0 requirements will be met: ** http://www.gnu.org/copyleft/gpl.html. ** ** 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. ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #ifndef TCFTRKENGINE_H #define TCFTRKENGINE_H #include "symbianutils_global.h" #include "tcftrkmessage.h" #include "callback.h" #include "json.h" #include #include #include #include #include QT_BEGIN_NAMESPACE class QIODevice; class QTextStream; QT_END_NAMESPACE namespace tcftrk { struct TcfTrkDevicePrivate; struct Breakpoint; /* Command error handling in TCF: * 1) 'Severe' errors (JSON format, parameter format): Trk emits a * nonstandard message (\3\2 error parameters) and closes the connection. * 2) Protocol errors: 'N' without error message is returned. * 3) Errors in command execution: 'R' with a TCF error hash is returned * (see TcfTrkCommandError). */ /* Error code return in 'R' reply to command * (see top of 'Services' documentation). */ struct SYMBIANUTILS_EXPORT TcfTrkCommandError { TcfTrkCommandError(); void clear(); operator bool() const { return timeMS != 0; } QString toString() const; void write(QTextStream &str) const; bool parse(const QVector &values); quint64 timeMS; // Since 1.1.1970 int code; QByteArray format; // message // 'Alternative' meaning, like altOrg="POSIX"/altCode= QByteArray alternativeOrganization; int alternativeCode; }; /* Answer to a Tcf command passed to the callback. */ struct SYMBIANUTILS_EXPORT TcfTrkCommandResult { enum Type { SuccessReply, // 'R' and no error -> all happy. CommandErrorReply, // 'R' with TcfTrkCommandError received ProgressReply, // 'P', progress indicator FailReply // 'N' Protocol NAK, severe error }; explicit TcfTrkCommandResult(Type t = SuccessReply); explicit TcfTrkCommandResult(char typeChar, Services service, const QByteArray &request, const QVector &values, const QVariant &cookie); QString toString() const; QString errorString() const; operator bool() const { return type == SuccessReply || type == ProgressReply; } Type type; Services service; QByteArray request; TcfTrkCommandError commandError; QVector values; QVariant cookie; }; typedef trk::Callback TcfTrkCallback; /* TcfTrkDevice: TCF communication helper using an asynchronous QIODevice * implementing the TCF protocol according to: http://dev.eclipse.org/svnroot/dsdp/org.eclipse.tm.tcf/trunk/docs/TCF%20Specification.html http://dev.eclipse.org/svnroot/dsdp/org.eclipse.tm.tcf/trunk/docs/TCF%20Services.html * Commands can be sent along with callbacks that are passed a * TcfTrkCommandResult and an opaque QVariant cookie. In addition, events are emitted. */ class SYMBIANUTILS_EXPORT TcfTrkDevice : public QObject { Q_PROPERTY(unsigned verbose READ verbose WRITE setVerbose) Q_OBJECT public: enum MessageType { MessageWithReply, MessageWithoutReply, /* Non-standard: "Settings:set" command does not reply */ NoopMessage }; typedef QSharedPointer IODevicePtr; explicit TcfTrkDevice(QObject *parent = 0); virtual ~TcfTrkDevice(); unsigned verbose() const; // Mapping of register names for indices QVector registerNames() const; void setRegisterNames(const QVector& n); IODevicePtr device() const; IODevicePtr takeDevice(); void setDevice(const IODevicePtr &dp); void sendTcfTrkMessage(MessageType mt, Services service, const char *command, const char *commandParameters, int commandParametersLength, const TcfTrkCallback &callBack = TcfTrkCallback(), const QVariant &cookie = QVariant()); void sendTcfTrkMessage(MessageType mt, Services service, const char *command, const QByteArray &commandParameters, const TcfTrkCallback &callBack = TcfTrkCallback(), const QVariant &cookie = QVariant()); // Convenience messages: Start a process void sendProcessStartCommand(const TcfTrkCallback &callBack, const QString &binary, unsigned uid, QStringList arguments = QStringList(), QString workingDirectory = QString(), bool debugControl = true, const QStringList &additionalLibraries = QStringList(), const QVariant &cookie = QVariant()); // Preferred over Processes:Terminate by TCF TRK. void sendRunControlTerminateCommand(const TcfTrkCallback &callBack, const QByteArray &id, const QVariant &cookie = QVariant()); void sendProcessTerminateCommand(const TcfTrkCallback &callBack, const QByteArray &id, const QVariant &cookie = QVariant()); // Non-standard: Remove executable from settings. // Probably needs to be called after stopping. This command has no response. void sendSettingsRemoveExecutableCommand(const QString &binaryIn, unsigned uid, const QStringList &additionalLibraries = QStringList(), const QVariant &cookie = QVariant()); void sendRunControlSuspendCommand(const TcfTrkCallback &callBack, const QByteArray &id, const QVariant &cookie = QVariant()); // Resume / Step (see RunControlResumeMode). void sendRunControlResumeCommand(const TcfTrkCallback &callBack, const QByteArray &id, RunControlResumeMode mode, unsigned count /* = 1, currently ignored. */, quint64 rangeStart, quint64 rangeEnd, const QVariant &cookie = QVariant()); // Convenience to resume a suspended process void sendRunControlResumeCommand(const TcfTrkCallback &callBack, const QByteArray &id, const QVariant &cookie = QVariant()); void sendBreakpointsAddCommand(const TcfTrkCallback &callBack, const Breakpoint &b, const QVariant &cookie = QVariant()); void sendBreakpointsRemoveCommand(const TcfTrkCallback &callBack, const QByteArray &id, const QVariant &cookie = QVariant()); void sendBreakpointsRemoveCommand(const TcfTrkCallback &callBack, const QVector &id, const QVariant &cookie = QVariant()); void sendBreakpointsEnableCommand(const TcfTrkCallback &callBack, const QByteArray &id, bool enable, const QVariant &cookie = QVariant()); void sendBreakpointsEnableCommand(const TcfTrkCallback &callBack, const QVector &id, bool enable, const QVariant &cookie = QVariant()); void sendMemoryGetCommand(const TcfTrkCallback &callBack, const QByteArray &contextId, quint64 start, quint64 size, const QVariant &cookie = QVariant()); void sendMemorySetCommand(const TcfTrkCallback &callBack, const QByteArray &contextId, quint64 start, const QByteArray& data, const QVariant &cookie = QVariant()); // Reply is an array of hexvalues void sendRegistersGetMCommand(const TcfTrkCallback &callBack, const QByteArray &contextId, const QVector &ids, const QVariant &cookie = QVariant()); // Convenience to get a range of register "R0" .. "R". // Cookie will be an int containing "start". void sendRegistersGetMRangeCommand(const TcfTrkCallback &callBack, const QByteArray &contextId, unsigned start, unsigned count); // Set register void sendRegistersSetCommand(const TcfTrkCallback &callBack, const QByteArray &contextId, const QByteArray &ids, unsigned value, const QVariant &cookie = QVariant()); // Set register void sendRegistersSetCommand(const TcfTrkCallback &callBack, const QByteArray &contextId, unsigned registerNumber, unsigned value, const QVariant &cookie = QVariant()); static QByteArray parseMemoryGet(const TcfTrkCommandResult &r); signals: void genericTcfEvent(int service, const QByteArray &name, const QVector &value); void tcfEvent(const tcftrk::TcfTrkEvent &knownEvent); void logMessage(const QString &); void error(const QString &); public slots: void setVerbose(unsigned v); private slots: void slotDeviceError(); void slotDeviceSocketStateChanged(); void slotDeviceReadyRead(); private: bool checkOpen(); void checkSendQueue(); void writeMessage(QByteArray data); void emitLogMessage(const QString &); int parseMessage(const QByteArray &); int parseTcfCommandReply(char type, const QVector &tokens); int parseTcfEvent(const QVector &tokens); TcfTrkDevicePrivate *d; }; } // namespace tcftrk #endif // TCFTRKENGINE_H