MNE-CPP  beta 1.0
babymegclient.cpp
1 //=============================================================================================================
37 //*************************************************************************************************************
38 //=============================================================================================================
39 // INCLUDES
40 //=============================================================================================================
41 
42 #include "babymegclient.h"
43 
44 //*************************************************************************************************************
45 //=============================================================================================================
46 // QT INCLUDES
47 //=============================================================================================================
48 
49 #include <QDebug>
50 #include <QtNetwork>
51 #include <QtEndian>
52 
53 
54 //*************************************************************************************************************
55 //=============================================================================================================
56 // DEFINE MEMBER METHODS
57 //=============================================================================================================
58 
59 BabyMEGClient::BabyMEGClient(int myPort, QObject *parent) :
60  QThread(parent)
61 {
62  connect(this,SIGNAL(DataAcq()),this,SLOT(run()));
63  tcpSocket = new QTcpSocket(this);
64 
65  connect(tcpSocket,SIGNAL(readyRead()),this,SLOT(ReadToBuffer()));
66 
67 
68  connect(this, SIGNAL(error(int,QString)),
69  this, SLOT(DisplayError(int,QString))); //find out name of this machine
70  name = QHostInfo::localHostName();
71  if(!name.isEmpty())
72  {
73  QString domain = QHostInfo::localDomainName();
74  if (!domain.isEmpty())
75  name = name + QChar('.') + domain;
76  }
77  if (name!=QString("localhost"))
78  name = QString("localhost");
79  qDebug()<< "- " + name;
80  port = myPort;//6340;
81  m_bSocketIsConnected = false;
82  SkipLoop = false;
83  DataAcqStartFlag = false;
84  numBlock = 0;
85  DataACK = false;
86 
87 }
88 
89 
90 //*************************************************************************************************************
91 
92 BabyMEGClient::~BabyMEGClient()
93 {
94  delete tcpSocket; // added 5.31.2013
95 }
96 
97 
98 //*************************************************************************************************************
99 
100 void BabyMEGClient::SetInfo(QSharedPointer<BabyMEGInfo> pInfo)
101 {
102  myBabyMEGInfo = pInfo;
103 }
104 
105 
106 //*************************************************************************************************************
107 
108 void BabyMEGClient::DisplayError(int socketError, const QString &message)
109 {
110  switch (socketError){
111  case QAbstractSocket::RemoteHostClosedError:
112  break;
113  case QAbstractSocket::HostNotFoundError:
114  qDebug()<< "The host was not found. Please check the host name and the port number";
115  break;
116  case QAbstractSocket::ConnectionRefusedError:
117  qDebug()<< "The connection was refused by the peer. Make sure the server is running?";
118  break;
119  default:
120  qDebug()<< "Error: " << message;
121  }
122 }
123 
124 
125 //*************************************************************************************************************
126 
127 int BabyMEGClient::MGH_LM_Byte2Int(QByteArray b)
128 {
129  int value= 0;
130  for (int i=0;i<2;i++)
131  {
132  QByteArray t;
133  t[0] = b[i];
134  b[i] = b[3-i];
135  b[3-i] = t[0];
136  }
137  memcpy((char *)&value,b,4);
138  return value;
139 }
140 
141 
142 //*************************************************************************************************************
143 
144 QByteArray BabyMEGClient::MGH_LM_Int2Byte(int a)
145 {
146  QByteArray b = QByteArray::fromRawData((char *)&a,4);
147 
148  for (int i=0;i<2;i++)
149  {
150  QByteArray t;
151  t[0] = b[i];
152  b[i] = b[3-i];
153  b[3-i] = t[0];
154  }
155  return b;
156 }
157 
158 
159 //*************************************************************************************************************
160 
161 double BabyMEGClient::MGH_LM_Byte2Double(QByteArray b)
162 {
163  double value= 1.0;
164  // reverse the byte order
165  for (int i=0;i<4;i++)
166  {
167  QByteArray t;
168  t[0] = b[i];
169  b[i] = b[7-i];
170  b[7-i] = t[0];
171  }
172  memcpy((char *)&value,b,8);
173 
174  return value;
175 }
176 
177 
178 //*************************************************************************************************************
179 
180 void BabyMEGClient::HexDisplay(double a)
181 {
182  QByteArray data = QByteArray::fromRawData((char *)&a,8);
183  qDebug() << data.toHex();
184 }
185 
186 
187 //*************************************************************************************************************
188 
190 {
191  // return true: sucessfully connect to babyMEG server
192  // false: fail.
193  m_bSocketIsConnected = false;
194  // Connect to the server of babyMEG [labview]
195  qDebug()<< "Client is started!";
196 
197  if (!this->isRunning())
198  {
199  this->start();
200  }
201 
202  for(int i = 0; i < 5; i++){
203  tcpSocket->connectToHost(name,port,QIODevice::ReadWrite);
204  if (tcpSocket->waitForConnected(5000))
205  {
206  m_bSocketIsConnected = true;
207  qDebug("Connect to BabyMEG Server ... Ok");
208  //download parameters
209  qDebug()<< "Send the initial parameter request";
210  if (tcpSocket->state()==QAbstractSocket::ConnectedState)
211  {
212  buffer.clear();
213 // SendCommand("INFO");
214  SendCommand("DATA");
215  }
216  return;
217  }
218  else{
219  qDebug("Connection to BabyMEG server failed");
220  qDebug("Retry...");
221  }
222  qDebug("Please check the babyMEG server: if started");
223  }
224  return;
225 }
226 
227 
228 //*************************************************************************************************************
229 
231 {
232  if(m_bSocketIsConnected && tcpSocket->state()==QAbstractSocket::ConnectedState)
233  SendCommand("QUIT");
234 }
235 
236 
237 //*************************************************************************************************************
238 
240 {
241  qDebug() << "SendCommandToBabyMEGShortConnection";
242 
243  bool connected = (tcpSocket->state() == QTcpSocket::ConnectedState);
244  if(connected)
245  {
246  tcpSocket->disconnectFromHost();
247  if(tcpSocket->state() != QAbstractSocket::UnconnectedState)
248  tcpSocket->waitForDisconnected();
249  }
250 
251  tcpSocket->connectToHost(name,port,QIODevice::ReadWrite);
252  if (tcpSocket->waitForConnected(10000))
253  {
254 
255  qDebug()<<"Connection is built.";
256 
257  if(tcpSocket->state()==QAbstractSocket::ConnectedState)
258  {
259  qDebug()<<"Send String [" << s << "]\n"<<"length["<<s.size()<<"]\n";
260  tcpSocket->write(s);
261 // int strlen = s.size();
262 // QByteArray Scmd = MGH_LM_Int2Byte(strlen);
263 
264 // tcpSocket->write(Scmd);
265 // tcpSocket->write("SLM");
266  tcpSocket->waitForBytesWritten();
267  }
268  else
269  {
270  qDebug()<<"Connect state is abnormal:"<<tcpSocket->state();
271  }
272  }
273 
274 }
275 
276 
277 //*************************************************************************************************************
278 
280 {
281  qDebug()<<"Send Command";
282  if(m_bSocketIsConnected && tcpSocket->state()==QAbstractSocket::ConnectedState)
283  {
284  m_qMutex.lock();
285  tcpSocket->write("COMD");
286  tcpSocket->waitForBytesWritten();
287 
288  int strlen = 3;
289  QByteArray Scmd = MGH_LM_Int2Byte(strlen);
290 
291  tcpSocket->write(Scmd);
292  tcpSocket->write("SLM");
293  tcpSocket->waitForBytesWritten();
294  m_qMutex.unlock();
295  }
296 
297 }
298 
299 
300 //*************************************************************************************************************
301 
303 {
304 
305  QByteArray dat;
306 
307  int numBytes = tcpSocket->bytesAvailable();
308 // qDebug() << "1.byte available: " << numBytes;
309  if (numBytes > 0){
310  dat = tcpSocket->read(numBytes); // read all pending data
311 // qDebug()<<"[dat Size]"<<dat.size();
312  if (!dat.isEmpty()){
313  buffer.append(dat); // and append it to your own buffer
314 // qDebug()<<"[ReadToBuffer: Buffer Size]"<<buffer.size();
315  }
316  else
317  {
318  qDebug()<<"[Empty dat: error]"<<tcpSocket->errorString();
319  }
320  }
321 // qDebug()<<"read buffer is done!";
322 
323  handleBuffer();
324  return;
325 }
326 
327 
328 //*************************************************************************************************************
329 
331 {
332  if(buffer.size()>= 8){
333  QByteArray CMD = buffer.left(4);
334  QByteArray DLEN = buffer.mid(4,4);
335  int tmp = MGH_LM_Byte2Int(DLEN);
336 // qDebug() << "First 4 bytes + length" << CMD << "["<<CMD.toHex()<<"]";
337 // qDebug() << "Command[" << CMD <<"]";
338 // qDebug() << "Body Length[" << tmp << "]";
339 
340  if (tmp <= (buffer.size() - 8))
341  {
342  buffer.remove(0,8);
343 
344  int OPT = 0;
345 
346  if (CMD == "INFO")
347  OPT = 1;
348  else if (CMD == "DATR")
349  OPT = 2;
350  else if (CMD == "COMD")
351  OPT = 3;
352  else if (CMD == "QUIT")
353  OPT = 4;
354  else if (CMD == "COMS")
355  OPT = 5;
356  else if (CMD == "QUIS")
357  OPT = 6;
358  else if (CMD == "INFG")
359  OPT = 7;
360 
361  switch (OPT){
362  case 1:
363  // from buffer get data package
364  {
365  QByteArray PARA = buffer.left(tmp);
366  qDebug()<<"[INFO]"<<PARA;
367  //Parse parameters from PARA string
368  myBabyMEGInfo->MGH_LM_Parse_Para(PARA);
369  buffer.remove(0,tmp);
370  qDebug()<<"INFO has been received!!!!";
371 // qDebug()<<"ACQ Start";
372 // SendCommand("DATA");
373  }
374  break;
375  case 2:
376  // read data package from buffer
377  // Ask for the next data block
378 
379  SendCommand("DATA");
380  DispatchDataPackage(tmp);
381 
382  break;
383  case 3:
384  {
385  QByteArray RESP = buffer.left(tmp);
386  qDebug()<< "5.Readbytes:"<<RESP.size();
387  qDebug() << RESP;
388  }
389  buffer.remove(0,tmp);
390 
391  break;
392  case 4: //quit
393  qDebug()<<"Quit";
394 
395  SendCommand("QREL");
396  tcpSocket->disconnectFromHost();
397  if(tcpSocket->state() != QAbstractSocket::UnconnectedState)
398  tcpSocket->waitForDisconnected();
399  m_bSocketIsConnected = false;
400  qDebug()<< "Disconnect Server";
401  qDebug()<< "Client is End!";
402  qDebug()<< "You can close this application or restart to connect Server.";
403 
404  break;
405  case 5://command short connection
406  {
407  QByteArray RESP = buffer.left(tmp);
408  qDebug()<< "5.Readbytes:"<<RESP.size();
409  qDebug() << RESP;
410  myBabyMEGInfo->MGH_LM_Send_CMDPackage(RESP);
411  }
412  buffer.remove(0,tmp);
413  SendCommand("QUIT");
414  break;
415  case 6: //quit
416  qDebug()<<"Quit";
417 
418  SendCommand("QREL");
419  tcpSocket->disconnectFromHost();
420  if(tcpSocket->state() != QAbstractSocket::UnconnectedState)
421  tcpSocket->waitForDisconnected();
422  m_bSocketIsConnected = false;
423  qDebug()<< "Disconnect Server";
424  break;
425  case 7: //INFG
426  {
427  QByteArray PARA = buffer.left(tmp);
428  qDebug()<<"[INFG]"<<PARA;
429  //Parse parameters from PARA string
430  myBabyMEGInfo->MGH_LM_Parse_Para_Infg(PARA);
431  buffer.remove(0,tmp);
432  qDebug()<<"INFG has been received!!!!";
433  }
434  break;
435 
436  default:
437  qDebug()<< "Unknow Type";
438  break;
439  }
440  }
441  }// buffer is not empty and larger than 8 bytes
442 
443 }
444 
445 
446 //*************************************************************************************************************
447 
449 {
450 
451 // qDebug()<<"Acq data from buffer [buffer size() =" << buffer.size()<<"]";
452  QByteArray DATA = buffer.left(tmp);
453  qDebug()<< "5.Readbytes:"<<DATA.size();
454  myBabyMEGInfo->MGH_LM_Send_DataPackage(DATA);
455 // myBabyMEGInfo->EnQueue(DATA);
456  buffer.remove(0,tmp);
457 // qDebug()<<"Rest buffer [buffer size() =" << buffer.size()<<"]";
458  numBlock ++;
459  qDebug()<< "Next Block ..." << numBlock;
460 // DATA.clear();
461 
462  ReadNextBlock(tmp);
463 }
464 
465 
466 //*************************************************************************************************************
467 
468 void BabyMEGClient::ReadNextBlock(int tmp)
469 {
470  QByteArray CMD1;
471  QByteArray DLEN1;
472  QByteArray DATA1;
473  int tmp1;
474  while (buffer.size()>=(tmp+8))
475  { // process the extra data block to reduce the load of data buffer
476  CMD1 = buffer.left(4);
477  qDebug()<<"CMD"<< CMD1;
478  if (CMD1 == "DATR")
479  {
480  DLEN1 = buffer.mid(4,4);
481  tmp1 = MGH_LM_Byte2Int(DLEN1);
482  qDebug() << "[2]First 4 bytes + length" << CMD1 << "["<<CMD1.toHex()<<"]";
483  qDebug() << "[2]Command[" << CMD1 <<"]";
484  qDebug() << "[2]Body Length[" << tmp1 << "]";
485 
486  buffer.remove(0,8);
487  DATA1 = buffer.left(tmp1);
488  myBabyMEGInfo->MGH_LM_Send_DataPackage(DATA1);
489 // myBabyMEGInfo->EnQueue(DATA1);
490  buffer.remove(0,tmp1);
491  qDebug()<<"End of DataPackeage" << buffer.left(3);
492  qDebug()<<"[2]Rest buffer [buffer size() =" << buffer.size()<<"]";
493  numBlock ++;
494  qDebug()<< "[2]Next Block ..." << numBlock;
495  }
496  else
497  {
498  qDebug()<<"[CMD1]"<<CMD1.toHex();
499  break;
500  }
501  qDebug()<<"[ReadNextBlock:buffer size]"<<buffer.size();
502  }
503  DATA1.clear();
504  CMD1.clear();
505  DLEN1.clear();
506 }
507 
508 
509 //*************************************************************************************************************
510 
511 void BabyMEGClient::SendCommand(QString s)
512 {
513  QByteArray array;
514  array.append(s);
515 
516  int WrtNum;
517 
518  if (tcpSocket->state()==QAbstractSocket::ConnectedState)
519  {
520  m_qMutex.lock();
521 
522 // qDebug()<<"[Send Command]"<<array;
523  WrtNum = tcpSocket->write(array,4);
524  if(WrtNum==-1)
525  {
526  qDebug()<<"Error for sending a command";
527  }
528  if(WrtNum != array.size())
529  {
530  qDebug()<<"Uncorrectly sending";
531  }
532  tcpSocket->flush();
533  tcpSocket->waitForBytesWritten();
534  m_qMutex.unlock();
535  qDebug()<<"[Done: Send Command]"<<array<<"[Send bytes]"<<WrtNum;
536 
537  }
538  else
539  {
540  qDebug()<<"Not in Connected state";
541  //re-connect to server
543  buffer.clear();
544  SendCommand("DATA");
545  }
546 // sleep(1);
547 }
548 
549 
550 //*************************************************************************************************************
551 
552 void BabyMEGClient::run()
553 {
554 
555 }
BabyMEGClient(int myPort, QObject *parent=0)
void MGH_LM_Parse_Para(QByteArray cmdstr)
void MGH_LM_Parse_Para_Infg(QByteArray cmdstr)
void SendCommandToBabyMEG()
void ReadNextBlock(int tmp)
void HexDisplay(double a)
void DisConnectBabyMEG()
void SendCommandToBabyMEGShortConnection(QByteArray s)
void SetInfo(BabyMEGInfo *pInfo)
void ConnectToBabyMEG()
double MGH_LM_Byte2Double(QByteArray InByte)
int MGH_LM_Byte2Int(QByteArray InByte)
void SendCommand(QString s)
QByteArray MGH_LM_Int2Byte(int a)
void DispatchDataPackage(int tmp)
void MGH_LM_Send_DataPackage(QByteArray DATA)
Definition: babymeginfo.cpp:56
void MGH_LM_Send_CMDPackage(QByteArray DATA)
Definition: babymeginfo.cpp:49