MNE-CPP  beta 1.0
commandthread.cpp
Go to the documentation of this file.
1 //=============================================================================================================
36 //*************************************************************************************************************
37 //=============================================================================================================
38 // INCLUDES
39 //=============================================================================================================
40 
41 #include "commandthread.h"
42 
43 
44 //*************************************************************************************************************
45 //=============================================================================================================
46 // QT INCLUDES
47 //=============================================================================================================
48 
49 #include <QtNetwork>
50 
51 
52 //*************************************************************************************************************
53 //=============================================================================================================
54 // USED NAMESPACES
55 //=============================================================================================================
56 
57 using namespace RTSERVER;
58 
59 
60 #define USENEWSERVER 1
61 
62 
63 //*************************************************************************************************************
64 //=============================================================================================================
65 // DEFINE MEMBER METHODS
66 //=============================================================================================================
67 
68 CommandThread::CommandThread(int socketDescriptor, qint32 p_iId, QObject *parent)
69 : QThread(parent)
70 , socketDescriptor(socketDescriptor)
71 , m_bIsRunning(false)
72 , m_iThreadID(p_iId)
73 {
74 
75 }
76 
77 
78 //*************************************************************************************************************
79 
80 CommandThread::~CommandThread()
81 {
82  m_bIsRunning = false;
83  QThread::wait();
84 }
85 
86 
87 //*************************************************************************************************************
88 
89 void CommandThread::attachCommandReply(QString p_blockReply, qint32 p_iID)
90 {
91  qDebug() << "CommandThread::attachCommandReply";
92  if(p_iID == m_iThreadID)
93  {
94  m_qMutex.lock();
95  m_qSendData = p_blockReply;
96  m_qMutex.unlock();
97  }
98 }
99 
100 
101 //*************************************************************************************************************
102 
103 void CommandThread::run()
104 {
105  m_bIsRunning = true;
106 
107  QTcpSocket t_qTcpSocket;
108 
109  if (!t_qTcpSocket.setSocketDescriptor(socketDescriptor)) {
110  emit error(t_qTcpSocket.error());
111  return;
112  }
113  else
114  {
115  printf("CommandClient connection accepted from\n\tIP:\t%s\n\tPort:\t%d\n\n",
116  QHostAddress(t_qTcpSocket.peerAddress()).toString().toUtf8().constData(),
117  t_qTcpSocket.peerPort());
118  }
119 
120  QDataStream t_FiffStreamIn(&t_qTcpSocket);
121  t_FiffStreamIn.setVersion(QDataStream::Qt_5_1);
122 
123 #ifndef USENEWSERVER
124  qint64 t_iMaxBufSize = 1024;
125 #endif
126 
127  while(t_qTcpSocket.state() != QAbstractSocket::UnconnectedState && m_bIsRunning)
128  {
129 #ifdef USENEWSERVER
130  //
131  // Write available data
132  //
133  if(m_qSendData.size() > 0)
134  {
135  QByteArray block;
136  QDataStream out(&block, QIODevice::WriteOnly);
137  out.setVersion(QDataStream::Qt_5_1);
138  out << (quint16)0;
139  m_qMutex.lock();
140  out << m_qSendData;
141  m_qSendData.clear();
142  m_qMutex.unlock();
143  out.device()->seek(0);
144  out << (quint16)(block.size() - sizeof(quint16));
145 
146  t_qTcpSocket.write(block);
147  t_qTcpSocket.waitForBytesWritten();
148  }
149 
150  //
151  // Read: Wait 100ms for incomming tag header, read and continue
152  //
153 
154  t_qTcpSocket.waitForReadyRead(100);
155 
156  if (t_qTcpSocket.bytesAvailable() >= (int)sizeof(quint16))
157  {
158  quint16 blockSize = 0;
159 
160  bool respComplete = false;
161  t_FiffStreamIn >> blockSize;
162 
163  while(!respComplete && blockSize < 65000)//Sanity Check -> allowed maximal blocksize is 65.000
164  {
165  if (t_qTcpSocket.bytesAvailable() >= blockSize)
166  {
167  QString t_sCommand;
168 
169  t_FiffStreamIn >> t_sCommand;
170 
171  t_sCommand = t_sCommand.simplified();
172 
173  //
174  // Parse command
175  //
176  if(!t_sCommand.isEmpty())
177  emit newCommand(t_sCommand, m_iThreadID);
178 
179  respComplete = true;
180  }
181  }
182  }
183 
184 #else
185  //
186  // Write available data
187  //
188  if(m_qSendBlock.size() > 0)
189  {
190  qint32 t_iBlockSize = m_qSendBlock.size();
191  m_qMutex.lock();
192  qint32 t_iBytesWritten = t_qTcpSocket.write(m_qSendBlock);
193  t_qTcpSocket.waitForBytesWritten();
194  if(t_iBytesWritten == t_iBlockSize)
195  m_qSendBlock.clear();
196  else
197  m_qSendBlock = m_qSendBlock.mid(t_iBytesWritten, t_iBlockSize-t_iBytesWritten);
198  m_qMutex.unlock();
199  }
200 
201  //
202  // Read: Wait 100ms for incomming tag header, read and continue
203  //
204  //ToDo its not the best solution in terms of receiving the command for sure
205  t_qTcpSocket.waitForReadyRead(100);
206 
207  if (t_qTcpSocket.bytesAvailable() > 0 && t_qTcpSocket.canReadLine())
208  {
209  QByteArray t_qByteArrayRaw = t_qTcpSocket.readLine(t_iMaxBufSize);
210  QString t_sCommand = QString(t_qByteArrayRaw).simplified();
211 
212  //
213  // Parse command
214  //
215  if(!t_sCommand.isEmpty())
216  emit newCommand(t_sCommand, m_iThreadID);
217  }
218  else if(t_qTcpSocket.bytesAvailable() > t_iMaxBufSize)
219  {
220  t_qTcpSocket.readAll();//readAll that QTcpSocket is empty again -> prevent overflow
221  }
222 #endif
223  }
224 
225  t_qTcpSocket.disconnectFromHost();
226  if(t_qTcpSocket.state() != QAbstractSocket::UnconnectedState)
227  t_qTcpSocket.waitForDisconnected();
228 }
implementation of the CommandThread Class.