MNE-CPP 0.1.9
A Framework for Electrophysiology
Loading...
Searching...
No Matches
rtcmdclient.cpp
Go to the documentation of this file.
1//=============================================================================================================
37//=============================================================================================================
38// INCLUDES
39//=============================================================================================================
40
41#include "rtcmdclient.h"
42
43//=============================================================================================================
44// QT INCLUDES
45//=============================================================================================================
46
47#include <QDateTime>
48#include <QThread>
49
50#include <iostream>
51
52#define USENEW 1
53
54//=============================================================================================================
55// USED NAMESPACES
56//=============================================================================================================
57
58using namespace COMMUNICATIONLIB;
59
60//=============================================================================================================
61// DEFINE MEMBER METHODS
62//=============================================================================================================
63
65: QTcpSocket(parent)
66{
67 QObject::connect(&m_commandManager, &CommandManager::triggered, this,
69}
70
71//=============================================================================================================
72
73QString RtCmdClient::sendCLICommand(const QString &p_sCommand)
74{
75 QString t_sCommand = QString("%1\n").arg(p_sCommand);
76 QString p_sReply;
77
78 if (this->state() == QAbstractSocket::ConnectedState)
79 {
80 this->write(t_sCommand.toUtf8().constData(), t_sCommand.size());
81 this->waitForBytesWritten();
82
83 //thats not the most elegant way
84 this->waitForReadyRead(1000);
85 QByteArray t_qByteArrayRaw;
86 // TODO(cpieloth): We need a break condition e.g. last byte == \0 or \n
87 // Large responses can be split to more than one packet which could be a problem on big network latencies.
88 while (this->bytesAvailable() > 0 && this->canReadLine())
89 t_qByteArrayRaw += this->readAll();
90
91 p_sReply = QString(t_qByteArrayRaw);
92 }
93 return p_sReply;
94}
95
96//=============================================================================================================
97
99{
100 const QString t_sCommand = QString("{\"commands\":{%1}}\n").arg(p_command.toStringReadySend());
101
102 QString t_sReply;
103
104 if (this->state() == QAbstractSocket::ConnectedState)
105 {
106 // Send request
107#ifdef USENEW
108 QByteArray block;
109 QDataStream out(&block, QIODevice::WriteOnly);
110 out.setVersion(QDataStream::Qt_5_1);
111
112 out << static_cast<quint16>(0);
113 out << t_sCommand;
114 out.device()->seek(0);
115 out << static_cast<quint16>(static_cast<unsigned long>(block.size()) - sizeof(quint16));
116
117 this->write(block);
118 this->waitForBytesWritten();
119
120 // Receive response
121 QDataStream in(this);
122 in.setVersion(QDataStream::Qt_5_1);
123
124 quint16 blockSize = 0;
125
126 bool respComplete = false;
127
128 do
129 {
130 this->waitForReadyRead(100);
131
132 if (blockSize == 0)
133 {
134 if (this->bytesAvailable() >= (int)sizeof(quint16))
135 in >> blockSize;
136 }
137 else if(this->bytesAvailable() >= blockSize)
138 {
139 in >> t_sReply;
140 respComplete = true;
141 }
142 } while (!respComplete && blockSize < 65000);//Sanity Check -> allowed maximal blocksize is 65.000
143#else
144 this->write(t_sCommand.toUtf8().constData(), t_sCommand.size());
145 this->waitForBytesWritten();
146
147 // Receive response
148 bool respComplete = false;
149 QByteArray t_qByteArrayRaw;
150 do
151 {
152 if (this->waitForReadyRead(100))
153 {
154 t_qByteArrayRaw += this->readAll();
155 // We need a break condition,
156 // because we do not have a stop character and do not know how many bytes to receive.
157 respComplete = t_qByteArrayRaw.count('{')
158 == t_qByteArrayRaw.count('}');
159 }
160 qDebug() << "Response: " << t_qByteArrayRaw.size() << " bytes";
161 } while (!respComplete);
162 t_sReply = QString(t_qByteArrayRaw);
163#endif
164 }
165 else
166 {
167 qWarning() << "Request was not send, because client is not connected!";
168 }
169
170 m_qMutex.lock();
171// m_sAvailableData.append(t_sReply); //ToDo check this
172 m_sAvailableData = t_sReply;
173 m_qMutex.unlock();
174
175 emit response(t_sReply);
176}
177
178//=============================================================================================================
179
181{
182 //Send
183 m_commandManager["getbufsize"].send();
184
185 //Receive
186 m_qMutex.lock();
187 QByteArray t_sJsonCommands = m_sAvailableData.toUtf8();
188 m_qMutex.unlock();
189
190 //Parse
191 QJsonParseError error;
192 QJsonDocument t_jsonDocumentOrigin = QJsonDocument::fromJson(t_sJsonCommands, &error);
193
194 if (error.error == QJsonParseError::NoError)
195 {
196// qDebug() << t_jsonDocumentOrigin;//"Received Commands" << m_commandManager.commandMap().keys();
197
198 //Switch to command object
199 if(t_jsonDocumentOrigin.isObject() && t_jsonDocumentOrigin.object().value(QString("bufsize")) != QJsonValue::Undefined)
200 {
201 qint32 size = (qint32)t_jsonDocumentOrigin.object().value(QString("bufsize")).toDouble();
202 return size;
203 }
204 }
205
206 qCritical() << "Unable to parse JSON response: " << error.errorString();
207 return -1;
208}
209
210//=============================================================================================================
211
213{
214 //No commands are present -> thats why help has to be send using a self created command
215 const QString help("help");
216 const QString description("");
217 const Command cmdHelp(help, description);
218 this->sendCommandJSON(cmdHelp);
219
220 //Clear Commands
221 m_commandManager.clear();
222
223 //Receive
224 m_qMutex.lock();
225 QByteArray t_sJsonCommands = m_sAvailableData.toUtf8();
226 m_qMutex.unlock();
227
228 //Parse
229 QJsonParseError error;
230 QJsonDocument t_jsonDocumentOrigin = QJsonDocument::fromJson(
231 t_sJsonCommands, &error);
232
233 if (error.error == QJsonParseError::NoError)
234 m_commandManager.insert(t_jsonDocumentOrigin);
235 else
236 qCritical() << "Unable to parse JSON response: " << error.errorString();
237}
238
239//=============================================================================================================
240
241qint32 RtCmdClient::requestConnectors(QMap<qint32, QString> &p_qMapConnectors)
242{
243 //Send
244 m_commandManager["conlist"].send();
245
246 //Receive
247 m_qMutex.lock();
248 QByteArray t_sJsonConnectors = m_sAvailableData.toUtf8();
249 m_qMutex.unlock();
250
251 //Parse
252 QJsonParseError error;
253 QJsonDocument t_jsonDocumentOrigin = QJsonDocument::fromJson(
254 t_sJsonConnectors, &error);
255
256 QJsonObject t_jsonObjectConnectors;
257
258 //Switch to command object
259 if(t_jsonDocumentOrigin.isObject() && t_jsonDocumentOrigin.object().value(QString("connectors")) != QJsonValue::Undefined)
260 t_jsonObjectConnectors = t_jsonDocumentOrigin.object().value(QString("connectors")).toObject();
261
262 //inits
263 qint32 p_iActiveId = -1;
264 p_qMapConnectors.clear();
265
266 //insert connectors
267 QJsonObject::Iterator it;
268 for(it = t_jsonObjectConnectors.begin(); it != t_jsonObjectConnectors.end(); ++it)
269 {
270 QString t_qConnectorName = it.key();
271
272 qint32 id = it.value().toObject().value(QString("id")).toDouble();
273
274 if(!p_qMapConnectors.contains(id))
275 p_qMapConnectors.insert(id, t_qConnectorName);
276 else
277 qWarning("Warning: CommandMap contains command %s already. Insertion skipped.\n", it.key().toUtf8().constData());
278
279 //if connector is active indicate it
280 if(it.value().toObject().value(QString("active")).toBool())
281 p_iActiveId = id;
282 }
283
284 return p_iActiveId;
285}
286
288
289//void RtCmdClient::requestMeasInfo(qint32 p_id)
290//{
291// QString t_sCommand = QString("measinfo %1").arg(p_id);
292// this->sendCommand(t_sCommand);
293//}
294
296
297//void RtCmdClient::requestMeasInfo(const QString &p_Alias)
298//{
299// QString t_sCommand = QString("measinfo %1").arg(p_Alias);
300// this->sendCommand(t_sCommand);
301//}
302
304
305//void RtCmdClient::requestMeas(qint32 p_id)
306//{
307// QString t_sCommand = QString("start %1").arg(p_id);
308// this->sendCommand(t_sCommand);
309//}
310
312
313//void RtCmdClient::requestMeas(QString p_Alias)
314//{
315// QString t_sCommand = QString("start %1").arg(p_Alias);
316// this->sendCommand(t_sCommand);
317//}
318
320
321//void RtCmdClient::stopAll()
322//{
323// QString t_sCommand = QString("stop-all");
324// this->sendCommand(t_sCommand);
325//}
326
327//=============================================================================================================
328
329bool RtCmdClient::waitForDataAvailable(qint32 msecs) const
330{
331 if (m_sAvailableData.size() > 0)
332 return true;
333
334 qint64 t_msecsStart = QDateTime::currentMSecsSinceEpoch();
335
336 while (msecs == -1
337 || (qint64) msecs
338 < QDateTime::currentMSecsSinceEpoch() - t_msecsStart)
339 {
340 QThread::msleep(5);
341 if (m_sAvailableData.size() > 0)
342 return true;
343 }
344 return false;
345}
346
347//=============================================================================================================
348
350{
351 return m_commandManager[key];
352}
353
354//=============================================================================================================
355
356const Command RtCmdClient::operator[](const QString &key) const
357{
358 return m_commandManager[key];
359}
declaration of the RtCmdClient Class.
Command & operator[](const QString &key)
void sendCommandJSON(const Command &p_command)
void response(QString p_sResponse)
qint32 requestConnectors(QMap< qint32, QString > &p_qMapConnectors)
RtCmdClient(QObject *parent=Q_NULLPTR)
QString sendCLICommand(const QString &p_sCommand)
bool waitForDataAvailable(qint32 msecs=30000) const
QString toStringReadySend() const
Definition command.cpp:202
void triggered(Command p_command)
void insert(const QJsonDocument &p_jsonDocument)