UsTK : Ultrasound ToolKit  version 2.0.1 under development (2024-05-21)
usNetworkServer.cpp
1 #include "usNetworkServer.h"
2 
3 usNetworkServer::usNetworkServer(QObject *parent) : QObject(parent)
4 {
5 
6  // init porta hardware
7  // creating porta object
8  m_porta = new porta;
9  std::cout << "porta instance created" << std::endl;
10 
11  m_usmVersion = 3;
12  m_pciVersion = 3;
13 
14  connectionSoc = NULL;
15 }
16 
18 
19 // This function is called whenever we have an incoming connection
20 void usNetworkServer::acceptTheConnection()
21 {
22 
23  // Accept and establish the connection. Note that, the data-transfer happens with `connectionSoc` and not with
24  // `tcpServer`
25  // `tcpServer` only waits and listens to new connections
26  connectionSoc = tcpServer.nextPendingConnection();
27 
28  // Set : readIncomingData() will be called whenever the data (coming from client) is available
29  connect(connectionSoc, SIGNAL(readyRead()), this, SLOT(readIncomingData()));
30 
31  // Set : connectionAboutToClose() will be called whenever the connection is close by the client
32  connect(connectionSoc, SIGNAL(disconnected()), this, SLOT(connectionAboutToClose()));
33 }
34 
35 // Will be called whenever the data (coming from client) is available
36 void usNetworkServer::readIncomingData()
37 {
38  // headers possible to be received
41 
42  // reading part
43 
44  // prepare reading in QDataStream
45  QDataStream in;
46  in.setDevice(connectionSoc);
47  in.setVersion(QDataStream::Qt_5_0);
48 
49  // read header id
50  int id;
51  in >> id;
52  std::cout << "id received : " << id << std::endl;
53 
54  if (id == 1) { // init header
55 
56  if (m_porta->isImaging()) // case of init received while an acquisition is already runnig
57  m_porta->stopImage();
58 
59  initWithoutUpdate = true;
60  in >> headerInit.probeId;
61  in >> headerInit.slotId;
62  in >> headerInit.imagingMode;
63 
64  initPorta(headerInit);
65 
66  // send back default params
67  QByteArray block;
68  QDataStream out(&block, QIODevice::WriteOnly);
69  out.setVersion(QDataStream::Qt_5_0);
70  out << confirmHeader.headerId;
71  out << confirmHeader.initOk;
72  out << confirmHeader.probeId;
73 
74  writeInitAcquisitionParameters(out, headerInit.imagingMode, headerInit.probeId);
75 
76  connectionSoc->write(block);
77  } else if (id == 2) { // update header
78 
79  if (m_porta->isImaging()) // case of update received while an acquisition is already runnig
80  m_porta->stopImage();
81 
82  initWithoutUpdate = false;
83 
84  in >> headerUpdate.transmitFrequency;
85  in >> headerUpdate.samplingFrequency;
86  in >> headerUpdate.imagingMode;
87  in >> headerUpdate.postScanMode;
88  in >> headerUpdate.postScanHeight;
89  in >> headerUpdate.postScanWidth;
90  in >> headerUpdate.imageDepth;
91  in >> headerUpdate.sector;
92  in >> headerUpdate.activateMotor;
93  in >> headerUpdate.motorPosition;
94  in >> headerUpdate.framesPerVolume;
95  in >> headerUpdate.stepsPerFrame;
96 
97  std::cout << "received header UPDATE = " << id << std::endl;
98  std::cout << "transmitFrequency = " << headerUpdate.transmitFrequency << std::endl;
99  std::cout << "samplingFrequency = " << headerUpdate.samplingFrequency << std::endl;
100  std::cout << "imagingMode = " << headerUpdate.imagingMode << std::endl;
101  std::cout << "postScanMode = " << headerUpdate.postScanMode << std::endl;
102  std::cout << "postScanHeigh = " << headerUpdate.postScanHeight << std::endl;
103  std::cout << "postScanWidtht = " << headerUpdate.postScanWidth << std::endl;
104  std::cout << "imageDepth = " << headerUpdate.imageDepth << std::endl;
105  std::cout << "sector = " << headerUpdate.sector << std::endl;
106  std::cout << "activateMotor = " << headerUpdate.activateMotor << std::endl;
107  std::cout << "motorPosition = " << headerUpdate.motorPosition << std::endl;
108  std::cout << "framesPerVolume = " << headerUpdate.framesPerVolume << std::endl;
109  std::cout << "degreesPerFrame = " << headerUpdate.stepsPerFrame << std::endl;
110 
111  if (updatePorta(headerUpdate)) { // sucess
112  // send back default params
113  QByteArray block;
114  QDataStream out(&block, QIODevice::WriteOnly);
115  out.setVersion(QDataStream::Qt_5_0);
116  out << confirmHeader.headerId;
117  out << confirmHeader.initOk;
118  out << confirmHeader.probeId;
119 
120  writeUpdateAcquisitionParameters(out, headerUpdate, confirmHeader.probeId);
121  std::cout << "bytes written to confirm update" << connectionSoc->write(block) << std::endl;
122  }
123  } else if (id == 3) { // run - stop command
124  std::cout << "received header RUN/STOP = " << id << std::endl;
125  bool run;
126  in >> run;
127 
128  std::cout << "command run = " << run << std::endl;
129 
130  if (run) {
131  probeInfo nfo;
132  m_porta->getProbeInfo(nfo);
133  if (initWithoutUpdate && nfo.motorized) {
134 #if USTK_PORTA_VERSION_MAJOR < 6
135  m_porta->setParam(prmMotorStatus, 0); // disables the motor
136 #endif
137  m_porta->setMotorActive(false);
138  }
139  if (!m_porta->runImage()) {
140  std::cout << "porta run error" << std::endl;
141  } else {
142  std::cout << "porta run OK" << std::endl;
143  }
144  } else {
145  m_porta->stopImage();
146 #if USTK_PORTA_VERSION_MAJOR < 6
147  m_porta->setParam(prmMotorStatus, 0); // disables the motor
148 #endif
149  m_porta->setMotorActive(false);
150  }
151  } else {
152  std::cout << "ERROR : unknown data received !" << std::endl;
153  }
154 }
155 
156 // Will be called whenever the connection is close by the client
157 void usNetworkServer::connectionAboutToClose()
158 {
159  // Set this text into the label
160  std::cout << "Connection to client closed" << std::endl;
161 
162  if (m_porta->isImaging())
163  m_porta->stopImage();
164 
165  // Close the connection (Say bye)
166  if(connectionSoc)
167  connectionSoc->close();
168 }
169 
171 #if USTK_PORTA_VERSION_MAJOR > 5 // used only for RF in sdk version >= 6
172 int portaCallback(void *param, unsigned char *addr, int blockIndex, int)
173 #else
174 bool portaCallback(void *param, unsigned char *addr, int blockIndex, int)
175 #endif
176 {
177  // std::cout << "new frame acquired" << std::endl;
178  usNetworkServer *server = (usNetworkServer *)param;
179  porta *portaInstance = server->getPorta();
180  QTcpSocket *socket = server->getSocket();
181 
182  if (portaInstance->getCurrentMode() != BiplaneMode)
183  server->imageHeader.frameCount++;
184  else if (server->imageHeader.frameCount == 0)
185  server->imageHeader.frameCount++;
186 
187  // manage motor offset at the beginning
188  int motorStatus;
189  portaInstance->getParam(prmMotorStatus, motorStatus);
190  if (!server->motorOffsetSkipped && (motorStatus == 1) && server->imageHeader.frameCount == 2) {
191  server->imageHeader.frameCount = 0;
192  server->motorOffsetSkipped = true;
193  }
194 
195  // std::cout << "frame count = " << server->imageHeader.frameCount << std::endl;
196  unsigned char *beginImage;
197  // filling image header
198 
199  quint64 oldTimeStamp = server->imageHeader.timeStamp; // for dataRate
200  server->imageHeader.timeStamp = QDateTime::currentMSecsSinceEpoch();
201 
202  server->imageHeader.dataRate = 1000.0 / (server->imageHeader.timeStamp - oldTimeStamp);
203 
204  if (server->imageHeader.imageType == 1) { // post scan
206  portaInstance->getBwImage(0, server->postScanImage, false);
207 
208  int mx, my;
209  portaInstance->getMicronsPerPixel(0, mx, my);
210 
211  // bi-plande case
212  if (portaInstance->getCurrentMode() == BiplaneMode) {
213  portaInstance->getBwImage(1, server->secondBiplaneImage, false);
214  // std::cout << "getting 2nd image from bi plane" << std::endl;
215  }
216  server->imageHeader.pixelHeight = my / 1000000.0;
217  server->imageHeader.pixelWidth = mx / 1000000.0;
218 
219  }
220  // data contains a 4 bytes header before image data
221  else if (server->imageHeader.imageType == 0) { // pre scan
222  server->imageHeader.dataLength = portaInstance->getParam(prmBNumLines) * portaInstance->getParam(prmBNumSamples);
223  beginImage = addr + 4;
224  server->imageHeader.pixelHeight = 0;
225  server->imageHeader.pixelWidth = 0;
226  } else if (server->imageHeader.imageType == 2) { // RF
227  int rfSize = portaInstance->getParam(prmRfNumLines) * portaInstance->getParam(prmRfNumSamples);
228  server->imageHeader.dataLength = rfSize * sizeof(short);
229  beginImage = addr + 4;
230  server->imageHeader.pixelHeight = 0;
231  server->imageHeader.pixelWidth = 0;
232  }
233 
234  server->beginImage = (char *)beginImage;
235  server->motorStatus = motorStatus;
236  server->biPlane = portaInstance->getCurrentMode() == BiplaneMode;
237 
239 
240  return true;
241 }
242 
244 #if USTK_PORTA_VERSION_MAJOR > 5
245 int portaCallbackImage(void *param, int id, int)
246 {
247  std::cout << "new frame acquired" << std::endl;
248  usNetworkServer *server = (usNetworkServer *)param;
249  porta *portaInstance = server->getPorta();
250  QTcpSocket *socket = server->getSocket();
251 
252  if (portaInstance->getCurrentMode() != BiplaneMode)
253  server->imageHeader.frameCount++;
254  else if (server->imageHeader.frameCount == 0)
255  server->imageHeader.frameCount++;
256 
257  // manage motor offset at the beginning
258  int motorStatus;
259  portaInstance->getParam(prmMotorStatus, motorStatus);
260  if (!server->motorOffsetSkipped && (motorStatus == 1) && server->imageHeader.frameCount == 2) {
261  server->imageHeader.frameCount = 0;
262  server->motorOffsetSkipped = true;
263  }
264 
265  unsigned char *beginImage;
266  // filling image header
267 
268  quint64 oldTimeStamp = server->imageHeader.timeStamp; // for dataRate
269  server->imageHeader.timeStamp = QDateTime::currentMSecsSinceEpoch();
270 
271  server->imageHeader.dataRate = 1000.0 / (server->imageHeader.timeStamp - oldTimeStamp);
272 
273  if (server->imageHeader.imageType == 1) { // post scan
275  portaInstance->getBwImage(0, server->postScanImage, false);
276 
277  int mx, my;
278  portaInstance->getMicronsPerPixel(0, mx, my);
279 
280  // bi-plande case
281  if (portaInstance->getCurrentMode() == BiplaneMode) {
282  portaInstance->getBwImage(1, server->secondBiplaneImage, false);
283  std::cout << "getting 2nd image from bi plane" << std::endl;
284  }
285  server->imageHeader.pixelHeight = my / 1000000.0;
286  server->imageHeader.pixelWidth = mx / 1000000.0;
287 
288  } else if (server->imageHeader.imageType == 0) { // pre scan
289  server->imageHeader.dataLength = portaInstance->getParam(prmBNumLines) * portaInstance->getParam(prmBNumSamples);
290 
291  beginImage = new unsigned char[portaInstance->getParam(prmBNumLines) * portaInstance->getParam(prmBNumSamples) *
292  sizeof(unsigned char)];
293  portaGetBwImagePrescan(0, beginImage);
294  server->imageHeader.pixelHeight = 0;
295  server->imageHeader.pixelWidth = 0;
296  }
297 
298  server->beginImage = (char *)beginImage;
299  server->motorStatus = motorStatus;
300  server->biPlane = portaInstance->getCurrentMode() == BiplaneMode;
301 
303 
304  return true;
305 }
306 #endif
307 
308 // porta init
309 void usNetworkServer::initPorta(usNetworkServer::usInitHeaderIncomming header)
310 {
311  // prepare return value
312  confirmHeader.initOk = 0;
313 
314  // check probe
315  char name[1024];
316  int code;
317  probeInfo nfo;
318 
319  if (m_porta->isConnected()) {
320  code = m_porta->getProbeID(header.slotId);
321  std::cout << "probe Id " << code << std::endl;
322  confirmHeader.probeId = code;
323  // select the code read
324  if (m_porta->selectProbe(code) && m_porta->getProbeInfo(nfo)) {
325  // Select slot passed by the header
326  if (m_porta->activateProbeConnector(header.slotId)) {
327 
328  if (m_porta->getProbeName(name, 1024, code)) {
329  std::cout << "detected probe : " << name << std::endl;
330  }
331  QString settingsPath = QString(USTK_PORTA_SETTINGS_PATH) + QString("presets/imaging/");
332  settingsPath += getProbeSettingsFromId(code);
333  m_porta->loadPreset(settingsPath.toStdString().c_str());
334 #if USTK_PORTA_VERSION_MAJOR > 5
335  int mode = header.imagingMode;
336  if (mode == 12) // RF
337  mode = BMode;
338  if (!m_porta->initImagingMode((imagingMode)mode)) { // in 6.x SDK, there is no more RF mode
339 #else
340  if (!m_porta->initImagingMode((imagingMode)header.imagingMode)) {
341 #endif
342  std::cout << "error initializing imaging mode" << std::endl;
343  } else {
344  if (code == header.probeId) {
345 
346 #if USTK_PORTA_VERSION_MAJOR > 5
347  if (header.imagingMode == RfMode)
348  m_porta->setRawDataCallback(portaCallback, (void *)this);
349  else
350  m_porta->setDisplayCallback(0, portaCallbackImage, (void *)this);
351 
352 #else
353  m_porta->setRawDataCallback(portaCallback, (void *)this);
354 #endif
355  // case of 3D, we disable motor by default and set it to middle frame
356  if (nfo.motorized) {
357  m_porta->goToPosition(0); // 0 = begin position
358 #if USTK_PORTA_VERSION_MAJOR <= 5
359  m_porta->setParam(prmMotorStatus, 0);
360 #endif
361  m_porta->setMotorActive(false);
362  imageHeader.motorRadius = nfo.motorRadius / 1000000.0; // from microns to meters
363  if (header.probeId == 15) // 4DC7
364  imageHeader.motorType = 1; // see usMotorType
365  else
367  }
368  m_currentImagingMode = (imagingMode)header.imagingMode;
369  confirmHeader.initOk = 1;
370  }
371  }
372  }
373  }
374  }
375 
376 // must set it to 128 for 4DC7 and C5-2 probes
377 #if USTK_PORTA_VERSION_MAJOR <= 5
378  m_porta->setParam(prmBLineDensity, 128);
379 #endif
380 
382  imageHeader.transducerRadius = nfo.radius / 1000000.0; // from microns to meters
383  imageHeader.scanLinePitch = (nfo.pitch / 1000000.0) / imageHeader.transducerRadius; // in meters
384 
385  int sector;
386  m_porta->getParam(prmBSector, sector);
387  imageHeader.scanLineNumber = m_porta->getParam(prmBLineDensity) * sector / 100;
388  imageHeader.degPerFrame = m_porta->getParam(prmMotorSteps) * (double)(nfo.motorFov / 1000.0) / (double)nfo.motorSteps;
389  imageHeader.motorRadius = nfo.motorRadius / 1000000.0; // from microns to meters
390  if (code == 15)
392  else
394 
395  int fpv;
396  m_porta->getParam(prmMotorFrames, fpv);
398 
399  imageHeader.transmitFrequency = m_porta->getParam(prmBTxFreq);
400  imageHeader.samplingFrequency = m_porta->getParam(prmBSamplingFreq);
401 
402  imageHeader.imageDepth = m_porta->getParam(prmBImageDepth);
403 
405 #if USTK_PORTA_VERSION_MAJOR > 5
406  portaRect rect;
407 #else
408  URect rect;
409 #endif
410  m_porta->getParam(prmBImageRect, rect);
411 
412  if (header.imagingMode == 12) { // RF
414  imageHeader.frameWidth = m_porta->getParam(prmRfNumLines);
415  imageHeader.frameHeight = m_porta->getParam(prmRfNumSamples);
416 #if USTK_PORTA_VERSION_MAJOR <= 5
417  m_porta->setParam(prmRfMode, 1);
418 #endif
419  imageHeader.ss = 16;
420  } else {
422  imageHeader.frameWidth = rect.right + 1;
423  imageHeader.frameHeight = rect.bottom;
424  imageHeader.ss = 8;
425 #if USTK_PORTA_VERSION_MAJOR > 5
426  m_porta->setDisplayDimensions(0, rect.right, rect.bottom);
427 #endif
428  }
429 
430  motorOffsetSkipped = false;
431  std::cout << "end init porta" << std::endl;
432 }
433 
434 bool usNetworkServer::updatePorta(usUpdateHeaderIncomming header)
435 {
436  bool initImagingMode;
437  // verify imaging mode
438  if (m_currentImagingMode != (imagingMode)header.imagingMode) {
439  // initialize new imaging mode
440  initImagingMode = m_porta->initImagingMode((imagingMode)header.imagingMode);
441  if (!initImagingMode) {
442  std::cout << "error initializing imaging mode" << std::endl;
443  return false;
444  }
445  } else
446  initImagingMode = true;
447 
448  if (initImagingMode) {
449  m_currentImagingMode = (imagingMode)header.imagingMode;
450  m_porta->setRawDataCallback(portaCallback, (void *)this);
451  // case of 3D
452  probeInfo nfo;
453  m_porta->getProbeInfo(nfo);
454  // Motor settings
455  if (nfo.motorized) {
456  // 2D
457  if (!header.activateMotor) {
458  m_porta->setMotorActive(true);
459  m_porta->goToPosition(header.motorPosition); // 0 = begin position
460  m_porta->setParam(prmMotorStatus, 0);
461  m_porta->setMotorActive(false);
462  }
463  // 3D
464  else {
465  m_porta->setParam(prmMotorFrames, header.framesPerVolume);
466  m_porta->setParam(prmMotorSteps, header.stepsPerFrame);
467  m_porta->setParam(prmMotorStatus, 1);
468  m_porta->setMotorActive(true);
469  }
470  }
471 
472  // RF - prescan
473  if (!header.postScanMode) {
474  if ((imagingMode)header.imagingMode == BMode) {
475 #if USTK_PORTA_VERSION_MAJOR > 5
476  portaRect rect;
477 #else
478  m_porta->setParam(prmRfMode, 0); // send only Bmode image
479  URect rect;
480 #endif
481  m_porta->getParam(prmBImageRect, rect);
482  imageHeader.frameWidth = rect.right + 1;
483  imageHeader.frameHeight = rect.bottom;
484  } else if ((imagingMode)header.imagingMode == RfMode) {
485  imageHeader.frameWidth = m_porta->getParam(prmRfNumLines);
486  imageHeader.frameHeight = m_porta->getParam(prmRfNumSamples);
487  }
488  } else { // post-scan
489  m_porta->setDisplayDimensions(0, header.postScanWidth, header.postScanHeight);
490  m_porta->getDisplayDimensions(0, imageHeader.frameWidth, imageHeader.frameHeight);
491  postScanImage = (unsigned char *)malloc(imageHeader.frameWidth * imageHeader.frameHeight * sizeof(unsigned char));
492 
493  // bi-plane
494  if ((imagingMode)header.imagingMode == BiplaneMode) {
495  m_porta->setDisplayDimensions(1, header.postScanWidth, header.postScanHeight);
497  (unsigned char *)malloc(imageHeader.frameWidth * imageHeader.frameHeight * sizeof(unsigned char));
498  }
499  }
500  // other acquisition parameters
501  if (m_porta->setParam(prmBImageDepth, header.imageDepth) && m_porta->setParam(prmBSector, header.sector) &&
502  m_porta->setParam(prmBTxFreq, header.transmitFrequency) &&
503  m_porta->setParam(prmBSamplingFreq, header.samplingFrequency)) {
504 
505  int sector;
506  m_porta->getParam(prmBSector, sector);
507  imageHeader.scanLineNumber = m_porta->getParam(prmBLineDensity) * sector / 100;
509  m_porta->getParam(prmMotorSteps) * (double)(nfo.motorFov / 1000.0) / (double)nfo.motorSteps;
510 
511  int fpv;
512  m_porta->getParam(prmMotorFrames, fpv);
514 
515  imageHeader.transmitFrequency = m_porta->getParam(prmBTxFreq);
516  imageHeader.samplingFrequency = m_porta->getParam(prmBSamplingFreq);
517 
518  imageHeader.imageDepth = m_porta->getParam(prmBImageDepth);
519 
520  if (!header.postScanMode) {
521  if ((imagingMode)header.imagingMode == BMode) {
522 #if USTK_PORTA_VERSION_MAJOR > 5
523  portaRect rect;
524 #else
525  URect rect;
526 #endif
527  m_porta->getParam(prmBImageRect, rect);
528  imageHeader.frameWidth = rect.right + 1;
529  imageHeader.frameHeight = rect.bottom;
530  } else if ((imagingMode)header.imagingMode == RfMode) {
531  imageHeader.frameWidth = m_porta->getParam(prmRfNumLines);
532  imageHeader.frameHeight = m_porta->getParam(prmRfNumSamples);
533  }
534  }
535 
536  if (header.postScanMode) {
538  imageHeader.ss = 8;
539  } else if (header.imagingMode == BMode) {
541  imageHeader.ss = 8;
542  } else if (header.imagingMode == RfMode) {
544  imageHeader.ss = 16;
545  }
546 
547  confirmHeader.initOk = 1;
548  return true;
549  }
550  }
551  return false;
552 }
553 
554 QTcpSocket *usNetworkServer::getSocket() { return connectionSoc; }
555 
556 porta *usNetworkServer::getPorta() { return m_porta; }
557 
558 QString usNetworkServer::getProbeSettingsFromId(int probeId)
559 {
560  QString settingName;
561 
562  // first we test if a config file is provided
563  if (usingProbeConfigFile) {
564  bool probeContainedInFile(false);
565  for (unsigned int i = 0; i < probeConfigFileNames.size(); i++) {
566  if (probeConfigFileNames.at(i).first == probeId) {
567  settingName = QString::fromStdString(probeConfigFileNames.at(i).second);
568  probeContainedInFile = true;
569  }
570  }
571  if (!probeContainedInFile) {
572  throw vpException(vpException::fatalError, std::string("Cannot find current probe id in \
573  config file provided with --probeSettingsFile option."));
574  }
575  } else {
576  if (probeId == 10) {
577  settingName = QString("FAST-General (C5-2 60mm).xml");
578  } else if (probeId == 12) {
579  settingName = QString("GEN-General (BPL9-5 55mm).xml");
580  } else if (probeId == 13) {
581  settingName = QString("GEN-General (BPC8-4 10mm).xml");
582  } else if (probeId == 14) {
583  settingName = QString("GEN-General (PAXY).xml");
584  } else if (probeId == 15) {
585  settingName = QString("GEN-General (4DC7-3 40mm).xml");
586  } else {
587  throw vpException(vpException::fatalError, std::string("Cannot compute current probe settings filename.\
588  Try to add a probe config file using --probeSettingsFile option at server startup."));
589  }
590  }
591  return settingName;
592 }
593 
594 void usNetworkServer::writeInitAcquisitionParameters(QDataStream &stream, int imagingMode, int probeId)
595 {
596  int transmitFrequency;
597  int samplingFrequency;
598  bool postScanMode = false;
599  int postScanHeight = 0;
600  int postScanWidth = 0;
601  int imageDepth;
602  int sector;
603  bool activateMotor = false;
604  int motorPosition = 0;
605  int framesPerVolume = 1;
606  int stepsPerFrame = 0;
607  int transmitFrequencyMin;
608  int samplingFrequencyMin;
609  int imagingModeMin = 0;
610  int imageDepthMin;
611  int sectorMin;
612  int motorPositionMin = 0;
613  int framesPerVolumeMin = 1;
614  int stepsPerFrameMin = 0;
615  int transmitFrequencyMax;
616  int samplingFrequencyMax;
617  int imagingModeMax = 27;
618  int imageDepthMax;
619  int sectorMax;
620  int motorPositionMax = 0;
621  int framesPerVolumeMax = 0;
622  int stepsPerFrameMax = 0;
623 
624  // case of 4DC7 probe
625  if (probeId == 15) {
626  motorPositionMax = 75;
627  framesPerVolumeMax = 31;
628 
629  m_porta->getParam(prmMotorSteps, stepsPerFrame);
630  m_porta->getParam(prmMotorFrames, framesPerVolume);
631  }
632 
633  m_porta->getParam(prmBTxFreq, transmitFrequency);
634  m_porta->getParam(prmBSamplingFreq, samplingFrequency);
635  m_porta->getParam(prmBImageDepth, imageDepth);
636  m_porta->getParam(prmBSector, sector);
637 
638  int motorStatus;
639  m_porta->getParam(prmMotorStatus, motorStatus);
640  if (motorStatus == 1) {
641  activateMotor = true;
642  }
643 
644  m_porta->getParamMinMax(prmBTxFreq, transmitFrequencyMin, transmitFrequencyMax);
645  m_porta->getParamMinMax(prmBSamplingFreq, samplingFrequencyMin, samplingFrequencyMax);
646  m_porta->getParamMinMax(prmBImageDepth, imageDepthMin, imageDepthMax);
647  m_porta->getParamMinMax(prmBSector, sectorMin, sectorMax);
648 
649  stream << transmitFrequency;
650  stream << samplingFrequency;
651  stream << imagingMode;
652  stream << postScanMode;
653  stream << postScanHeight;
654  stream << postScanWidth;
655  stream << imageDepth;
656  stream << sector;
657  stream << activateMotor;
658  stream << motorPosition;
659  stream << framesPerVolume;
660  stream << stepsPerFrame;
661  stream << transmitFrequencyMin;
662  stream << samplingFrequencyMin;
663  stream << imagingModeMin;
664  stream << imageDepthMin;
665  stream << sectorMin;
666  stream << motorPositionMin;
667  stream << framesPerVolumeMin;
668  stream << stepsPerFrameMin;
669  stream << transmitFrequencyMax;
670  stream << samplingFrequencyMax;
671  stream << imagingModeMax;
672  stream << imageDepthMax;
673  stream << sectorMax;
674  stream << motorPositionMax;
675  stream << framesPerVolumeMax;
676  stream << stepsPerFrameMax;
677 }
678 
679 void usNetworkServer::writeUpdateAcquisitionParameters(QDataStream &stream, usUpdateHeaderIncomming header, int probeId)
680 {
681 
682  int framesPerVolume = 1;
683  int stepsPerFrame = 0;
684 
685  int transmitFrequencyMin;
686  int samplingFrequencyMin;
687  int imagingModeMin = 0;
688  int imageDepthMin;
689  int sectorMin;
690  int motorPositionMin = 0;
691  int framesPerVolumeMin = 1;
692  int stepsPerFrameMin = 0;
693 
694  int transmitFrequencyMax;
695  int samplingFrequencyMax;
696  int imagingModeMax = 27;
697  int imageDepthMax;
698  int sectorMax;
699  int motorPositionMax = 0;
700  int framesPerVolumeMax = 1;
701  int stepsPerFrameMax = 0;
702 
703  if (probeId == 15) { // for 4DC7
704  stepsPerFrame = 8;
705  motorPositionMax = 75;
706  framesPerVolumeMax = 31;
707 
708  m_porta->getParam(prmMotorSteps, stepsPerFrame);
709  m_porta->getParam(prmMotorFrames, framesPerVolume);
710  }
711 
712  m_porta->getParam(prmBTxFreq, header.transmitFrequency);
713  m_porta->getParam(prmBSamplingFreq, header.samplingFrequency);
714  m_porta->getDisplayDimensions(0, header.postScanWidth, header.postScanHeight);
715  m_porta->getParam(prmBImageDepth, header.imageDepth);
716  m_porta->getParam(prmBSector, header.sector);
717 
718  int motorStatus;
719  m_porta->getParam(prmMotorStatus, motorStatus);
720  header.activateMotor = (motorStatus == 1);
721  std::cout << "writeUpdateAcquisitionParameters(), motor status = " << motorStatus << std::endl;
722 
723  m_porta->getParamMinMax(prmBTxFreq, transmitFrequencyMin, transmitFrequencyMax);
724  m_porta->getParamMinMax(prmBSamplingFreq, samplingFrequencyMin, samplingFrequencyMax);
725  m_porta->getParamMinMax(prmBImageDepth, imageDepthMin, imageDepthMax);
726  m_porta->getParamMinMax(prmBSector, sectorMin, sectorMax);
727 
728  stream << header.transmitFrequency;
729  stream << header.samplingFrequency;
730  stream << header.imagingMode;
731  stream << header.postScanMode;
732  stream << header.postScanHeight;
733  stream << header.postScanWidth;
734  stream << header.imageDepth;
735  stream << header.sector;
736  stream << header.activateMotor;
737  stream << header.motorPosition;
738  stream << framesPerVolume;
739  stream << stepsPerFrame;
740  stream << transmitFrequencyMin;
741  stream << samplingFrequencyMin;
742  stream << imagingModeMin;
743  stream << imageDepthMin;
744  stream << sectorMin;
745  stream << motorPositionMin;
746  stream << framesPerVolumeMin;
747  stream << stepsPerFrameMin;
748  stream << transmitFrequencyMax;
749  stream << samplingFrequencyMax;
750  stream << imagingModeMax;
751  stream << imageDepthMax;
752  stream << sectorMax;
753  stream << motorPositionMax;
754  stream << framesPerVolumeMax;
755  stream << stepsPerFrameMax;
756 }
757 
759 
760 void usNetworkServer::writeOnSocketSlot()
761 {
762  QByteArray block;
763 
764  if (verboseMode) {
765  std::cout << "writing header on socket" << std::endl;
766  std::cout << "image number : " << imageHeader.frameCount << std::endl;
767  }
768  QDataStream out(&block, QIODevice::WriteOnly);
769  out.setVersion(QDataStream::Qt_5_0);
770  out << imageHeader.headerId;
771  out << imageHeader.frameCount;
772  out << imageHeader.timeStamp;
773  out << imageHeader.dataRate;
774  out << imageHeader.dataLength;
775  out << imageHeader.ss;
776  out << imageHeader.imageType;
777  out << imageHeader.frameWidth;
778  out << imageHeader.frameHeight;
779  out << imageHeader.pixelWidth;
780  out << imageHeader.pixelHeight;
784  out << imageHeader.scanLinePitch;
786  out << imageHeader.imageDepth;
787  out << imageHeader.degPerFrame;
789  out << imageHeader.motorRadius;
790  out << imageHeader.motorType;
791 
792  if (verboseMode) {
793  std::cout << "writing image on socket" << std::endl;
794  }
795  if (imageHeader.imageType == 1) { // post scan
796  out.writeRawData((char *)postScanImage, imageHeader.dataLength);
797  } else if (imageHeader.imageType == 0) { // pre-scan
798  out.writeRawData((char *)beginImage, imageHeader.dataLength);
799  } else if (imageHeader.imageType == 2) { // RF
800  out.writeRawData((char *)beginImage, imageHeader.dataLength);
801  }
802 
803  quint64 dataWrittenSize = 0;
804 
805  if (motorOffsetSkipped && (motorStatus == 1)) { // 3D but offset skipped
806  dataWrittenSize = connectionSoc->write(block);
807  } else if (motorStatus == 0) { // 2D
808  dataWrittenSize = connectionSoc->write(block);
809  }
810 
811  if (verboseMode) {
812  std::cout << "written data size = " << dataWrittenSize << std::endl;
813  }
814  // for bi-plane we send a second image
815  if (biPlane && imageHeader.imageType == 1) {
816  QByteArray block;
817  // std::cout << "writing 2nd header" << std::endl;
818  QDataStream out(&block, QIODevice::WriteOnly);
819  out.setVersion(QDataStream::Qt_5_0);
820  out << imageHeader.headerId;
821  out << imageHeader.frameCount;
822  out << imageHeader.timeStamp;
823  out << imageHeader.dataRate;
824  out << imageHeader.dataLength;
825  out << imageHeader.ss;
826  out << imageHeader.imageType;
827  out << imageHeader.frameWidth;
828  out << imageHeader.frameHeight;
829  out << imageHeader.pixelWidth;
830  out << imageHeader.pixelHeight;
834  out << imageHeader.scanLinePitch;
836  out << imageHeader.imageDepth;
837  out << imageHeader.degPerFrame;
839  out << imageHeader.motorRadius;
840  out << imageHeader.motorType;
841 
842  if (verboseMode) {
843  std::cout << "writing 2nd image" << std::endl;
844  }
845  out.writeRawData((char *)secondBiplaneImage, imageHeader.dataLength);
847 
848  connectionSoc->write(block);
849  }
850 }
851 
852 void usNetworkServer::quitApp()
853 {
854  connectionAboutToClose();
855  qApp->exit();
856 }
857 
858 void usNetworkServer::useProbeConfigFile(std::string configFileName)
859 {
860  usingProbeConfigFile = true;
861 
862  // opens config file provided
863  std::ifstream file;
864  if (!vpIoTools::checkFilename(configFileName)) {
865  std::cout << "file does not exist\n";
866  }
867 
868  file.open(configFileName.c_str(), std::ifstream::in);
869  if (!file.good()) {
870  throw vpException(vpException::ioError, std::string("Error opening probe config file."));
871  }
872 
873  // fills the vector of probes id and associated config filenames
874  int probeId;
875  std::string keyNum, keyFileName;
876  std::string::iterator it;
877  while (file.good()) {
878  std::getline(file, keyNum, ' ');
879  it = keyNum.end();
880  keyNum.erase(std::remove(keyNum.begin(), keyNum.end(), ' '), it);
881 
882  probeId = stoi(keyNum);
883  std::getline(file, keyFileName, '\n');
884 
885  std::pair<int, std::string> newElement;
886  newElement.first = probeId;
887  newElement.second = keyFileName;
888 
889  probeConfigFileNames.push_back(newElement);
890  }
891  file.close();
892 }
893 
894 void usNetworkServer::setVerbose() { verboseMode = true; }
895 
897  // porta settings
898  char *portaFirmware = USTK_PORTA_FIRMWARE_PATH;
899  char *portaSettings = USTK_PORTA_SETTINGS_PATH;
900  char *portaLicense = USTK_PORTA_LICENSE_PATH;
901  char *portaLut = "";
902 
903  int highVoltage = 0; // true only if version 2
904 
905  // init porta
906  bool initPortaSucess = m_porta->init(256 * 1024 * 1024, portaFirmware, portaSettings, portaLicense, portaLut, m_usmVersion,
907  m_pciVersion, highVoltage, 0, 64);
908  if (!initPortaSucess) {
909  std::cout << "error initializing porta sdk !" << std::endl;
910  }
911 
912 
913  // init TCP server
914  // set : acceptTheConnection() will be called whenever there is a new connection
915  connect(&tcpServer, SIGNAL(newConnection()), this, SLOT(acceptTheConnection()));
916 
917  // Start listening on port 8080
918  QString portNum = QString::number(8080);
919  bool status = tcpServer.listen(QHostAddress::Any, portNum.toUShort());
920 
921  // Check, if the server did start correctly or not
922  if (status == true) {
923  std::cout << "TCP server Started\nServer now listening on port# " << portNum.toStdString() << std::endl;
924  } else {
925  std::cout << "TCP server start failure" << tcpServer.errorString().toStdString() << std::endl;
926  }
927 
928  usingProbeConfigFile = false;
929  verboseMode = false;
930 
931  connect(this, SIGNAL(writeOnSocketSignal()), this, SLOT(writeOnSocketSlot()));
932 }
933 
935  quitApp();
936 }
937 
938 
939 void usNetworkServer::setUSMVersion(int usmVersion) {
940  m_usmVersion = usmVersion;
941 }
942 
943 void usNetworkServer::setPCIVersion(int pciVersion) {
944  m_pciVersion = pciVersion;
945 }
QTcpSocket * getSocket()
void useProbeConfigFile(std::string configFileName)
void setPCIVersion(int pciVersion)
void writeOnSocketFromOtherThread()
void setUSMVersion(int usmVersion)
usNetworkServer(QObject *parent=0)
void writeOnSocketSignal()
unsigned char * secondBiplaneImage
unsigned char * postScanImage
usImageHeader imageHeader