|
1 /**************************************************************************** |
|
2 ** |
|
3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). |
|
4 ** All rights reserved. |
|
5 ** Contact: Nokia Corporation (qt-info@nokia.com) |
|
6 ** |
|
7 ** This file is part of the tools applications of the Qt Toolkit. |
|
8 ** |
|
9 ** $QT_BEGIN_LICENSE:LGPL$ |
|
10 ** No Commercial Usage |
|
11 ** This file contains pre-release code and may not be distributed. |
|
12 ** You may use this file in accordance with the terms and conditions |
|
13 ** contained in the Technology Preview License Agreement accompanying |
|
14 ** this package. |
|
15 ** |
|
16 ** GNU Lesser General Public License Usage |
|
17 ** Alternatively, this file may be used under the terms of the GNU Lesser |
|
18 ** General Public License version 2.1 as published by the Free Software |
|
19 ** Foundation and appearing in the file LICENSE.LGPL included in the |
|
20 ** packaging of this file. Please review the following information to |
|
21 ** ensure the GNU Lesser General Public License version 2.1 requirements |
|
22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. |
|
23 ** |
|
24 ** In addition, as a special exception, Nokia gives you certain additional |
|
25 ** rights. These rights are described in the Nokia Qt LGPL Exception |
|
26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. |
|
27 ** |
|
28 ** If you have questions regarding the use of this file, please contact |
|
29 ** Nokia at qt-info@nokia.com. |
|
30 ** |
|
31 ** |
|
32 ** |
|
33 ** |
|
34 ** |
|
35 ** |
|
36 ** |
|
37 ** |
|
38 ** $QT_END_LICENSE$ |
|
39 ** |
|
40 ****************************************************************************/ |
|
41 |
|
42 #ifndef TCFTRKENGINE_H |
|
43 #define TCFTRKENGINE_H |
|
44 |
|
45 #include "symbianutils_global.h" |
|
46 #include "tcftrkmessage.h" |
|
47 #include "callback.h" |
|
48 #include "json.h" |
|
49 |
|
50 #include <QtCore/QObject> |
|
51 #include <QtCore/QSharedPointer> |
|
52 #include <QtCore/QVector> |
|
53 #include <QtCore/QVariant> |
|
54 #include <QtCore/QStringList> |
|
55 |
|
56 QT_BEGIN_NAMESPACE |
|
57 class QIODevice; |
|
58 class QTextStream; |
|
59 QT_END_NAMESPACE |
|
60 |
|
61 namespace tcftrk { |
|
62 |
|
63 struct TcfTrkDevicePrivate; |
|
64 struct Breakpoint; |
|
65 |
|
66 /* Command error handling in TCF: |
|
67 * 1) 'Severe' errors (JSON format, parameter format): Trk emits a |
|
68 * nonstandard message (\3\2 error paramaters) and closes the connection. |
|
69 * 2) Protocol errors: 'N' without error message is returned. |
|
70 * 3) Errors in command execution: 'R' with a TCF error hash is returned |
|
71 * (see TcfTrkCommandError). */ |
|
72 |
|
73 /* Error code return in 'R' reply to command |
|
74 * (see top of 'Services' documentation). */ |
|
75 struct SYMBIANUTILS_EXPORT TcfTrkCommandError { |
|
76 TcfTrkCommandError(); |
|
77 void clear(); |
|
78 operator bool() const { return timeMS != 0; } |
|
79 QString toString() const; |
|
80 void write(QTextStream &str) const; |
|
81 bool parse(const QVector<JsonValue> &values); |
|
82 |
|
83 quint64 timeMS; // Since 1.1.1970 |
|
84 int code; |
|
85 QByteArray format; // message |
|
86 // 'Alternative' meaning, like altOrg="POSIX"/altCode=<some errno> |
|
87 QByteArray alternativeOrganization; |
|
88 int alternativeCode; |
|
89 }; |
|
90 |
|
91 /* Answer to a Tcf command passed to the callback. */ |
|
92 struct SYMBIANUTILS_EXPORT TcfTrkCommandResult { |
|
93 enum Type { |
|
94 SuccessReply, // 'R' and no error -> all happy. |
|
95 CommandErrorReply, // 'R' with TcfTrkCommandError received |
|
96 ProgressReply, // 'P', progress indicator |
|
97 FailReply // 'N' Protocol NAK, severe error |
|
98 }; |
|
99 |
|
100 explicit TcfTrkCommandResult(Type t = SuccessReply); |
|
101 explicit TcfTrkCommandResult(char typeChar, Services service, |
|
102 const QByteArray &request, |
|
103 const QVector<JsonValue> &values, |
|
104 const QVariant &cookie); |
|
105 |
|
106 QString toString() const; |
|
107 QString errorString() const; |
|
108 operator bool() const { return type == SuccessReply || type == ProgressReply; } |
|
109 |
|
110 Type type; |
|
111 Services service; |
|
112 QByteArray request; |
|
113 TcfTrkCommandError commandError; |
|
114 QVector<JsonValue> values; |
|
115 QVariant cookie; |
|
116 }; |
|
117 |
|
118 typedef trk::Callback<const TcfTrkCommandResult &> TcfTrkCallback; |
|
119 |
|
120 /* TcfTrkDevice: TCF communication helper using an asynchronous QIODevice |
|
121 * implementing the TCF protocol according to: |
|
122 http://dev.eclipse.org/svnroot/dsdp/org.eclipse.tm.tcf/trunk/docs/TCF%20Specification.html |
|
123 http://dev.eclipse.org/svnroot/dsdp/org.eclipse.tm.tcf/trunk/docs/TCF%20Services.html |
|
124 * Commands can be sent along with callbacks that are passed a |
|
125 * TcfTrkCommandResult and an opaque QVariant cookie. In addition, events are emitted. |
|
126 */ |
|
127 |
|
128 class SYMBIANUTILS_EXPORT TcfTrkDevice : public QObject |
|
129 { |
|
130 Q_PROPERTY(unsigned verbose READ verbose WRITE setVerbose) |
|
131 Q_OBJECT |
|
132 public: |
|
133 enum MessageType { MessageWithReply, |
|
134 MessageWithoutReply, /* Non-standard: "Settings:set" command does not reply */ |
|
135 NoopMessage }; |
|
136 |
|
137 typedef QSharedPointer<QIODevice> IODevicePtr; |
|
138 |
|
139 explicit TcfTrkDevice(QObject *parent = 0); |
|
140 virtual ~TcfTrkDevice(); |
|
141 |
|
142 unsigned verbose() const; |
|
143 |
|
144 // Mapping of register names for indices |
|
145 QVector<QByteArray> registerNames() const; |
|
146 void setRegisterNames(const QVector<QByteArray>& n); |
|
147 |
|
148 IODevicePtr device() const; |
|
149 IODevicePtr takeDevice(); |
|
150 void setDevice(const IODevicePtr &dp); |
|
151 |
|
152 void sendTcfTrkMessage(MessageType mt, Services service, |
|
153 const char *command, |
|
154 const char *commandParameters, int commandParametersLength, |
|
155 const TcfTrkCallback &callBack = TcfTrkCallback(), |
|
156 const QVariant &cookie = QVariant()); |
|
157 |
|
158 void sendTcfTrkMessage(MessageType mt, Services service, const char *command, |
|
159 const QByteArray &commandParameters, |
|
160 const TcfTrkCallback &callBack = TcfTrkCallback(), |
|
161 const QVariant &cookie = QVariant()); |
|
162 |
|
163 // Convenience messages: Start a process |
|
164 void sendProcessStartCommand(const TcfTrkCallback &callBack, |
|
165 const QString &binary, |
|
166 unsigned uid, |
|
167 QStringList arguments = QStringList(), |
|
168 QString workingDirectory = QString(), |
|
169 bool debugControl = true, |
|
170 const QStringList &additionalLibraries = QStringList(), |
|
171 const QVariant &cookie = QVariant()); |
|
172 |
|
173 // Preferred over Processes:Terminate by TCF TRK. |
|
174 void sendRunControlTerminateCommand(const TcfTrkCallback &callBack, |
|
175 const QByteArray &id, |
|
176 const QVariant &cookie = QVariant()); |
|
177 |
|
178 void sendProcessTerminateCommand(const TcfTrkCallback &callBack, |
|
179 const QByteArray &id, |
|
180 const QVariant &cookie = QVariant()); |
|
181 |
|
182 // Non-standard: Remove executable from settings. |
|
183 // Probably needs to be called after stopping. This command has no response. |
|
184 void sendSettingsRemoveExecutableCommand(const QString &binaryIn, |
|
185 unsigned uid, |
|
186 const QStringList &additionalLibraries = QStringList(), |
|
187 const QVariant &cookie = QVariant()); |
|
188 |
|
189 void sendRunControlSuspendCommand(const TcfTrkCallback &callBack, |
|
190 const QByteArray &id, |
|
191 const QVariant &cookie = QVariant()); |
|
192 |
|
193 // Resume / Step (see RunControlResumeMode). |
|
194 void sendRunControlResumeCommand(const TcfTrkCallback &callBack, |
|
195 const QByteArray &id, |
|
196 RunControlResumeMode mode, |
|
197 unsigned count /* = 1, currently ignored. */, |
|
198 quint64 rangeStart, quint64 rangeEnd, |
|
199 const QVariant &cookie = QVariant()); |
|
200 |
|
201 // Convenience to resume a suspended process |
|
202 void sendRunControlResumeCommand(const TcfTrkCallback &callBack, |
|
203 const QByteArray &id, |
|
204 const QVariant &cookie = QVariant()); |
|
205 |
|
206 void sendBreakpointsAddCommand(const TcfTrkCallback &callBack, |
|
207 const Breakpoint &b, |
|
208 const QVariant &cookie = QVariant()); |
|
209 |
|
210 void sendBreakpointsRemoveCommand(const TcfTrkCallback &callBack, |
|
211 const QByteArray &id, |
|
212 const QVariant &cookie = QVariant()); |
|
213 |
|
214 void sendBreakpointsRemoveCommand(const TcfTrkCallback &callBack, |
|
215 const QVector<QByteArray> &id, |
|
216 const QVariant &cookie = QVariant()); |
|
217 |
|
218 void sendBreakpointsEnableCommand(const TcfTrkCallback &callBack, |
|
219 const QByteArray &id, |
|
220 bool enable, |
|
221 const QVariant &cookie = QVariant()); |
|
222 |
|
223 void sendBreakpointsEnableCommand(const TcfTrkCallback &callBack, |
|
224 const QVector<QByteArray> &id, |
|
225 bool enable, |
|
226 const QVariant &cookie = QVariant()); |
|
227 |
|
228 |
|
229 void sendMemoryGetCommand(const TcfTrkCallback &callBack, |
|
230 const QByteArray &contextId, |
|
231 quint64 start, quint64 size, |
|
232 const QVariant &cookie = QVariant()); |
|
233 |
|
234 void sendMemorySetCommand(const TcfTrkCallback &callBack, |
|
235 const QByteArray &contextId, |
|
236 quint64 start, const QByteArray& data, |
|
237 const QVariant &cookie = QVariant()); |
|
238 |
|
239 // Reply is an array of hexvalues |
|
240 void sendRegistersGetMCommand(const TcfTrkCallback &callBack, |
|
241 const QByteArray &contextId, |
|
242 const QVector<QByteArray> &ids, |
|
243 const QVariant &cookie = QVariant()); |
|
244 |
|
245 // Convenience to get a range of register "R0" .. "R<n>". |
|
246 // Cookie will be an int containing "start". |
|
247 void sendRegistersGetMRangeCommand(const TcfTrkCallback &callBack, |
|
248 const QByteArray &contextId, |
|
249 unsigned start, unsigned count); |
|
250 |
|
251 // Set register |
|
252 void sendRegistersSetCommand(const TcfTrkCallback &callBack, |
|
253 const QByteArray &contextId, |
|
254 const QByteArray &ids, |
|
255 unsigned value, |
|
256 const QVariant &cookie = QVariant()); |
|
257 // Set register |
|
258 void sendRegistersSetCommand(const TcfTrkCallback &callBack, |
|
259 const QByteArray &contextId, |
|
260 unsigned registerNumber, |
|
261 unsigned value, |
|
262 const QVariant &cookie = QVariant()); |
|
263 |
|
264 static QByteArray parseMemoryGet(const TcfTrkCommandResult &r); |
|
265 |
|
266 signals: |
|
267 void genericTcfEvent(int service, const QByteArray &name, const QVector<tcftrk::JsonValue> &value); |
|
268 void tcfEvent(const tcftrk::TcfTrkEvent &knownEvent); |
|
269 |
|
270 void logMessage(const QString &); |
|
271 void error(const QString &); |
|
272 |
|
273 public slots: |
|
274 void setVerbose(unsigned v); |
|
275 |
|
276 private slots: |
|
277 void slotDeviceError(); |
|
278 void slotDeviceSocketStateChanged(); |
|
279 void slotDeviceReadyRead(); |
|
280 |
|
281 private: |
|
282 bool checkOpen(); |
|
283 void checkSendQueue(); |
|
284 void writeMessage(QByteArray data); |
|
285 void emitLogMessage(const QString &); |
|
286 int parseMessage(const QByteArray &); |
|
287 int parseTcfCommandReply(char type, const QVector<QByteArray> &tokens); |
|
288 int parseTcfEvent(const QVector<QByteArray> &tokens); |
|
289 |
|
290 TcfTrkDevicePrivate *d; |
|
291 }; |
|
292 |
|
293 } // namespace tcftrk |
|
294 |
|
295 #endif // TCFTRKENGINE_H |