Cat
Server_NI6008.cpp
Go to the documentation of this file.
1 #include "Server_NI6008.h"
2 
3 int main(int argc, char *argv[]){
4  int port = 5555;
5  if (argc>2) {
6  fprintf(stderr,"usage: %s port[=5555].\n", argv[1]);
7  exit(0);}
8  if (argc==2) port = atoi(argv[1]);
9  Server_NI6008 server(port);
10 }
11 
12 #ifndef NODAQ
13 #define DAQmxErrChk(functionCall) { if( DAQmxFailed(error=(functionCall)) ) { goto Error; } }
14 #endif
15 
16 //-----------------------------------------------------------------------------
17 // Implementation file for class : Server_NI6008
18 //
19 // 2016-05-27 :
20 //-----------------------------------------------------------------------------
21 
22 //=============================================================================
23 // Standard constructor, initializes variables
24 //=============================================================================
26  callSize (18),
27  lineLength (200),
28  m_aiMin(-10.0),
29  m_aiMax(10.0),
30  m_aoMin(0.0),
31  m_aoMax(5.0),
32  m_timeout(10.0)
33 {
34  portno = port;
35 
36  colors.push_back(std::string("\033[94m"));
37  colors.push_back(std::string("\033[92m"));
38  colors.push_back(std::string("\033[93m"));
39  colors.push_back(std::string("\033[95m"));
40  colors.push_back(std::string("\033[33m"));
41  colors.push_back(std::string("\033[91m"));
42  colors.push_back(std::string("\033[0m"));
43 
44  std::string _accountName = accountName();
45  std::string _hostName = hostName();
46  std::string _osName = osName();
47  std::string _osVersion = osVersion();
48 
49  msgSvc(INFO,"","");
50  msgSvc(INFO," ***********************************************","");
51  msgSvc(INFO," * C A T *","");
52  msgSvc(INFO," * *","");
53  msgSvc(INFO," * |\\-''-/|.___..--''\"`-._ *","");
54  msgSvc(INFO," * `6_ 6 ) `-. ( ).`-.__.`) *","");
55  msgSvc(INFO," * (_Y_.)' ._ ) `._ `. ``-..-' *","");
56  msgSvc(INFO," * _..`--'_..- _/ /--'_.' ,' *","");
57  msgSvc(INFO," * (il),-'' (li),' ((!.-' *","");
58  msgSvc(INFO," ***********************************************","");
59  msgSvc(INFO,"","");
60  msgSvc(INFO,"Application running on "+
61  _accountName+"@"+
62  _hostName+" ("+
63  _osName+" - "+
64  _osVersion+")","");
65 
66  msgSvc(INFO, "Connecting port "+itos(port),"Server_NI6008");
67 
68 #ifdef NODAQ
69  msgSvc(WARNING,"NO HARDWARE - FAKE ACQUISITION");
70 #endif
71  start();
72 }
73 
74 //=============================================================================
75 // Destructor
76 //=============================================================================
78 }
79 
80 //=============================================================================
81 //
82 //=============================================================================
83 void Server_NI6008::error(const char *msg)
84 {
85  perror(msg);
86  exit(1);
87 }
88 
89 //=============================================================================
90 //
91 //=============================================================================
93  std::string msg,
94  std::string call ){
95  const int OUTLEVEL = DEBUG;
96  if (level<OUTLEVEL) return;
97  log ( level, msg, call);
98 }
99 
100 //=============================================================================
101 //
102 //=============================================================================
104  time_t rawtime;
105  struct tm * timeinfo;
106 
107  time ( &rawtime );
108  timeinfo = localtime ( &rawtime );
109  char* timechar = asctime (timeinfo) ;
110  std::string timing = std::string(timechar,24) + " ";
111 
112  return timing;
113 }
114 
115 //=============================================================================
116 //
117 //=============================================================================
119  std::string msg,
120  std::string call){
121 
122  bool isFatal=false;
123 
124  //#ifndef WIN32
125  std::string output(colors[BLUE]);
126  output+=std::string(call,0,callSize);
127  //#else
128  // std::string output=std::string(call,0,callSize);
129  //#endif
130 
131 
132 
133  int clen=call.length();
134 
135  if (clen>0)
136  {
137  if (clen>callSize) output.replace(callSize+5-3,3,"...");
138  if (clen<callSize) output.insert (clen+5,callSize-clen,' ');
139  }
140 
141  std::string color;
142 
143  switch(level) {
144  case VERBOSE:
145  color=colors[BLUE];
146  output+=color;
147  output+=" VERBOSE ";
148  break;
149  case DEBUG:
150  color=colors[BLUE];
151  output+=color;
152  output+=" DEBUG ";
153  break;
154  case INFO:
155  color=colors[GREEN];
156  output+=color;
157  output+=" INFO ";
158  break;
159  case WARNING:
160  color=colors[YELLOW];
161  output+=color;
162  output+=" WARNING ";
163  break;
164  case ERR:
165  color=colors[MAGENTA];
166  output+=color;
167  output+=" ERROR ";
168  break;
169  case FATAL:
170  color=colors[RED];
171  output+=color;
172  output+=" FATAL ";
173  isFatal=true;
174  break;
175  default:
176  color = colors[CYAN];
177  output+=color;
178  output = call;
179  break;
180  }
181  output+=colors[WHITE];
182  output+=logtime();
183  output+=color;
184  output+=msg;
185  output+=colors[WHITE];
186 
187  std::cout << output << std::endl;
188 
189  if (isFatal) {exit(0);}
190 }
191 
192 //=============================================================================
193 //
194 //=============================================================================
196  sockfd = socket(AF_INET, SOCK_STREAM, 0);
197  if (sockfd < 0)
198  error("ERROR opening socket");
199  bzero((char *) &serv_addr, sizeof(serv_addr));
200  serv_addr.sin_family = AF_INET;
201  serv_addr.sin_addr.s_addr = INADDR_ANY;
202  serv_addr.sin_port = htons(portno);
203  if (bind(sockfd, (struct sockaddr *) &serv_addr,
204  sizeof(serv_addr)) < 0)
205  error("ERROR on binding");
206  listen(sockfd,5);
207  clilen = sizeof(cli_addr);
208  newsockfd = accept(sockfd,
209  (struct sockaddr *) &cli_addr,
210  &clilen);
211  if (newsockfd < 0) error("ERROR on accept");
212  while(1) {
213  bzero(buffer,256);
214  cmd();
215  }
216  close(newsockfd);
217  close(sockfd);
218 }
219 
220 //=============================================================================
221 //
222 //=============================================================================
224  n = read(newsockfd,buffer,255);
225  if (n < 0) {
226  error("ERROR reading from socket");
227  }
228 
229  char result[4096];
230  int size = 0 ;
231 
232  std::string newcmd = std::string(buffer);
233  std::string delimiter = " ";
234  size_t pos = 0;
235  int cmdsize = 0;
236  std::vector<std::string> cmdvec;
237  while ((pos = newcmd.find(delimiter)) != std::string::npos) {
238  cmdvec.push_back(newcmd.substr(0, pos));
239  newcmd.erase(0, pos + delimiter.length());
240  cmdsize++;
241  }
242  cmdvec.push_back(newcmd);
243  cmdsize++;
244  // for (int i =0 ; i<cmdsize; i++) std::cout<<" command: "<<cmdvec[i]<<" "<<cmdsize<<std::endl;
245 
246  bool understood = false;
247  std::string instr = cmdvec[1];
248  std::transform(instr.begin(), instr.end(),instr.begin(), ::tolower);
249  size = -1 ;
250  // Server status
251  if ( instr=="status"){
252  // status();
253  understood = true;
254  }
255  // Time out
256  if ( instr=="timeout" && cmdsize==2 ){
257  setTimeout(atof(cmdvec[2].c_str()));
258  // status();
259  understood = true;
260  }
261  // AI
262  if ( instr=="ai" && cmdsize==2 ){
263  const char* dev = cmdvec[0].c_str();
264  double data[4];
265  AI(dev, data);
266  size = sprintf(result,"%f %f %f %f", data[0], data[1], data[2], data[3]);
267  if ( write(newsockfd, result, size)<0 ) error("ERROR writing to socket");
268  understood = true;
269  }
270  // AI range
271  if ( instr=="airange" && cmdsize==4 ){
272  setAIRange(atof(cmdvec[2].c_str()), atof(cmdvec[3].c_str()));
273  // status();
274  understood = true;
275  }
276  // AO
277  if ( instr=="ao" && cmdsize==4){
278  const char* dev = cmdvec[0].c_str();
279  double data[2];
280  data[0]=atof(cmdvec[2].c_str());
281  data[1]=atof(cmdvec[3].c_str());
282  // std::cout<<data[0]<<" "<<data[1]<<std::endl;
283  AO(dev, data);
284  size = sprintf(result,"AO set.");
285  if ( write(newsockfd, result, size)<0 ) error("ERROR writing to socket");
286  understood = true;
287  }
288  // // AO0
289  // if ( instr=="ao0" && cmdsize==1){
290  // double data;
291  // data=atof(cmdvec[1].c_str());
292  // AO0(data);
293  // size = sprintf(result,"AO0 set.");
294  // if ( write(newsockfd, result, size)<0 ) error("ERROR writing to socket");
295  // }
296  // // AO1
297  // if ( instr=="ao1" && cmdsize==1){
298  // double data;
299  // data=atof(cmdvec[1].c_str());
300  // AO1(data);
301  // size = sprintf(result,"AO1 set.");
302  // if ( write(newsockfd, result, size)<0 ) error("ERROR writing to socket");
303  // }
304  // AO range
305  if ( instr=="aorange" && cmdsize==4 ){
306  setAORange(atof(cmdvec[2].c_str()), atof(cmdvec[3].c_str()));
307  // status();
308  understood = true;
309  }
310  // DI
311  if ( instr=="di"){
312  const char* dev = cmdvec[0].c_str();
313  unsigned char idata[2];
314  DI(dev, idata);
315  unsigned int data = idata[0]+256*idata[1];
316  unsigned int data2 =
317  (data>>3&1)+2*(data>>2&1)+4*(data>>1&1)+8*(data&1)+
318  16*(data>>11&1)+32*(data>>10&1)+64*(data>>9&1)+128*(data>>8&1)+
319  256*(data>>7&1)+512*(data>>6&1)+1024*(data>>5&1)+2048*(data>>4&1);
320 
321  size = sprintf(result,"%d %d - %d / %d -> %i%i%i%i%i%i%i%i%i%i%i%i ", idata[0], idata[1], data, data2,
322  data>>11&1, data>>10& 1, data>>9&1, data>>8&1,
323  data>>7&1, data>>6&1, data>>5&1, data>>4&1,
324  data>>3&1, data>>2&1, data>>1&1, data&1
325  );
326  std::cout<< "digit :" << result<< std::endl;
327  if ( write(newsockfd, result, size)<0 ) error("ERROR writing to socket");
328  understood = true;
329  }
330  // DI
331  if ( instr=="reset"){
332  Reset();
333  if ( write(newsockfd, result, size)<0 ) error("ERROR writing to socket");
334  understood = true;
335  }
336  // Stop
337  if ( instr=="stop"){
338  msgSvc(WARNING, "Closing the server connection.");
339  n = send("exit");
340  if (n < 0) error("ERROR writing to socket");
341  close(newsockfd);
342  close(sockfd);
343  exit(0);
344  }
345  if (!understood){
346  size = sprintf(result,"Instruction not understood.");
347  if ( write(newsockfd, result, size)<0 ) error("ERROR writing to socket");
348  }
349  return 0;
350 }
351 
352 //=============================================================================
353 //
354 //=============================================================================
356  send(std::string("Port : "+itos(portno)));
357  send(std::string(" - Timeout = "+ftos(m_timeout)));
358  send(std::string(" - AI"));
359  send(std::string(" . min = "+ftos(m_aiMin)));
360  send(std::string(" . max = "+ftos(m_aiMax)));
361  send(std::string(" - AO"));
362  send(std::string(" . min = "+ftos(m_aoMin)));
363  send(std::string(" . max = "+ftos(m_aoMax)));
364 }
365 //=============================================================================
366 //
367 //=============================================================================
368 int Server_NI6008::AI(const char* dev, double data[4]){
369  // Task parameters
370  int32 error = 0;
371  TaskHandle taskHandle = 0;
372  char errBuff[2048]={'\0'};
373  char chan[80];
374  sprintf(chan,"%s/ai0,%s/ai1,%s/ai2,%s/ai3", dev, dev, dev, dev);
375 
376  // std::cout<<chan<<std::endl;
377 
378  // Channel parameters
379  float64 min = -10.0;
380  float64 max = 10.0;
381 
382  // Timing parameters
383  uInt64 samplesPerChan = 4;
384 
385  // Data read parameters
386  int32 pointsToRead = 1;
387  int32 pointsRead;
388  float64 timeout = m_timeout;
389 
390 #ifndef NODAQ
391 
392  DAQmxErrChk (DAQmxBaseCreateTask("",&taskHandle));
393  DAQmxErrChk (
394  DAQmxBaseCreateAIVoltageChan(taskHandle,
395  chan,
396  "",
397  DAQmx_Val_Cfg_Default,
398  min,max,
399  DAQmx_Val_Volts,
400  NULL));
401  DAQmxErrChk (DAQmxBaseStartTask(taskHandle));
402  DAQmxErrChk (DAQmxBaseReadAnalogF64(taskHandle,
403  pointsToRead,
404  timeout,
405  DAQmx_Val_GroupByChannel,
406  data,
407  samplesPerChan,
408  &pointsRead,
409  NULL));
410 Error:
411  if( DAQmxFailed(error) )
412  DAQmxBaseGetExtendedErrorInfo(errBuff,2048);
413  if( taskHandle!=0 ) {
414  DAQmxBaseStopTask(taskHandle);
415  DAQmxBaseClearTask(taskHandle);
416  }
417  if( DAQmxFailed(error) )
418  printf ("DAQmxBase Error %ld: %s\n", error, errBuff);
419 #endif
420  sprintf(errBuff,"Readout AI: Ch %s - Val = %2.4f %2.4f %2.4f %2.4f", chan, data[0], data[1], data[2], data[3]);
421  std::cout<<errBuff<<std::endl;
422  return 0;
423 }
424 
425 //=============================================================================
426 //
427 //=============================================================================
428 int Server_NI6008::AO(const char *dev, double data[2]){
429  // Task parameters
430  int code = 0;
431  int32 error = 0;
432  TaskHandle taskHandle = 0;
433  char errBuff[2048]={'\0'};
434  char chan[80];
435  sprintf(chan,"%s/ao0,%s/ao1", dev, dev);
436  // char chan[] = "Dev1/ao0,Dev1/ao1";
437 
438  // Channel parameters
439  float64 min = m_aoMin;
440  float64 max = m_aoMax;
441  // Timing parameters
442  uInt64 samplesPerChan = 1;
443  // Data write parameters
444  int32 pointsWritten;
445 
446 #ifndef NODAQ
447 
448  DAQmxErrChk (DAQmxBaseCreateTask("",&taskHandle));
449  DAQmxErrChk (DAQmxBaseCreateAOVoltageChan(taskHandle,
450  chan,
451  "",
452  min,max,
453  DAQmx_Val_Volts,
454  NULL));
455  DAQmxErrChk (DAQmxBaseStartTask(taskHandle));
456 
457  DAQmxErrChk (DAQmxBaseWriteAnalogF64(taskHandle,
458  samplesPerChan,
459  0,
460  m_timeout,
461  DAQmx_Val_GroupByChannel,
462  data,
463  &pointsWritten,NULL)
464  );
465 Error:
466  if( DAQmxFailed(error) )
467  DAQmxBaseGetExtendedErrorInfo(errBuff,2048);
468  if( taskHandle!=0 ) {
469  DAQmxBaseStopTask(taskHandle);
470  DAQmxBaseClearTask(taskHandle);
471  }
472  if( DAQmxFailed(error) )
473  printf ("DAQmxBase Error %ld: %s\n", error, errBuff);
474 #endif
475  sprintf(errBuff,"Setting AO: Ch %s - Val = %2.2f %2.2f", chan, data[0], data[1]);
476  std::cout<<errBuff<<std::endl;
477  return 0;
478 }
479 
480 //=============================================================================
481 //
482 //=============================================================================
483 int Server_NI6008::DI(const char *dev, unsigned char r_data[2] ) {
484  // Task parameters
485  int code = 0;
486  int32 error = 0;
487  TaskHandle taskHandle = 0;
488  int32 i;
489  const uInt32 num_ports = 2;
490  char errBuff[2048];
491 
492  // Channel parameters
493  char chan1[32];
494  char chan2[32];
495 
496  sprintf(chan1,"%s/port0", dev);
497  sprintf(chan2,"%s/port1", dev);
498  // char chan1[] = "Dev1/port0";
499  // char chan2[] = "Dev1/port1";
500 
501  // Read parameters
502  int32 read;
503 
504 #ifndef NODAQ
505  // Create Digital Input (DI) Task and Channel
506  DAQmxErrChk (DAQmxBaseCreateTask ("", &taskHandle));
507  DAQmxErrChk (DAQmxBaseCreateDIChan(taskHandle,chan1,"",DAQmx_Val_ChanForAllLines));
508  DAQmxErrChk (DAQmxBaseCreateDIChan(taskHandle,chan2,"",DAQmx_Val_ChanForAllLines));
509 
510  // Start Task (configure port)
511  DAQmxErrChk (DAQmxBaseStartTask (taskHandle));
512 
513  // Read from port
514  DAQmxErrChk (
515  code = DAQmxBaseReadDigitalU8(
516  taskHandle,
517  1,
518  m_timeout,
519  DAQmx_Val_GroupByChannel,
520  r_data,
521  num_ports,
522  &read,
523  NULL)
524  );
525  // msgSvc(INFO,"Processing DI "+std::string(chan1)+"/"+std::string(chan2)+
526  // " ->"+ itos(r_data[0])+", "+itos(r_data[1]));
527 
528 Error:
529 
530  if (DAQmxFailed (error))
531  DAQmxBaseGetExtendedErrorInfo (errBuff, 2048);
532  if (taskHandle != 0){
533  DAQmxBaseStopTask (taskHandle);
534  DAQmxBaseClearTask (taskHandle);
535  }
536  if (error)printf ("DAQmxBase Error %ld: %s\n", error, errBuff);
537 #endif
538  sprintf(errBuff,"Reading DI: Ch %s %s - Val = %3i %3i", chan1, chan2, r_data[0], r_data[1]);
539  std::cout<<errBuff<<std::endl;
540  return 0;
541 }
542 
543 //=============================================================================
544 //
545 //=============================================================================
547  msgSvc(INFO,"Reset has not been implemented yet.");
548  return 0;
549 }
550 
551 //=============================================================================
552 //
553 //=============================================================================
555  // Task parameters
556  int code = 0;
557  int32 error = 0;
558  TaskHandle taskHandle = 0;
559  char errBuff[2048]={'\0'};
560  char chan[] = "Dev1/ao0\0";
561  // Channel parameters
562  float64 min = m_aoMin;
563  float64 max = m_aoMax;
564  // Timing parameters
565  uInt64 samplesPerChan = 1;
566  // Data write parameters
567  int32 pointsWritten;
568 
569 #ifndef NODAQ
570 
571  DAQmxErrChk (DAQmxBaseCreateTask("",&taskHandle));
572  DAQmxErrChk (DAQmxBaseCreateAOVoltageChan(taskHandle,
573  chan,
574  "",
575  min,max,
576  DAQmx_Val_Volts,
577  NULL));
578  DAQmxErrChk (DAQmxBaseStartTask(taskHandle));
579 
580  DAQmxErrChk (DAQmxBaseWriteAnalogF64(taskHandle,
581  samplesPerChan,
582  0,
583  m_timeout,
584  DAQmx_Val_GroupByChannel,
585  &data,
586  &pointsWritten,NULL)
587  );
588  msgSvc(INFO,"Processing AO "+std::string(chan)+".");
589  return code;
590 
591 Error:
592  if( DAQmxFailed(error) )
593  DAQmxBaseGetExtendedErrorInfo(errBuff,2048);
594  if( taskHandle!=0 ) {
595  DAQmxBaseStopTask(taskHandle);
596  DAQmxBaseClearTask(taskHandle);
597  }
598  if( DAQmxFailed(error) )
599  printf ("DAQmxBase Error %ld: %s\n", error, errBuff);
600 #endif
601  return 0;
602 }
603 
604 //=============================================================================
605 //
606 //=============================================================================
608  // Task parameters
609  int code = 0;
610  int32 error = 0;
611  TaskHandle taskHandle = 0;
612  char errBuff[2048]={'\0'};
613  char chan[] = "Dev1/ao1";
614  // Channel parameters
615  float64 min = m_aoMin;
616  float64 max = m_aoMax;
617  // Timing parameters
618  uInt64 samplesPerChan = 1;
619  // Data write parameters
620  int32 pointsWritten;
621 
622  #ifndef NODAQ
623  DAQmxErrChk (DAQmxBaseCreateTask("",&taskHandle));
624  DAQmxErrChk (DAQmxBaseCreateAOVoltageChan(taskHandle,
625  chan,
626  "",
627  min,max,
628  DAQmx_Val_Volts,
629  NULL));
630  DAQmxErrChk (DAQmxBaseStartTask(taskHandle));
631 
632  DAQmxErrChk (DAQmxBaseWriteAnalogF64(taskHandle,
633  samplesPerChan,
634  0,
635  m_timeout,
636  DAQmx_Val_GroupByChannel,
637  &data,
638  &pointsWritten,NULL)
639  );
640  msgSvc(INFO,"Processing AO1 "+std::string(chan)+".");
641 #endif
642  return code;
643 
644 #ifndef NODAQ
645 Error:
646  if( DAQmxFailed(error) )
647  DAQmxBaseGetExtendedErrorInfo(errBuff,2048);
648  if( taskHandle!=0 ) {
649  DAQmxBaseStopTask(taskHandle);
650  DAQmxBaseClearTask(taskHandle);
651  }
652  if( DAQmxFailed(error) )
653  printf ("DAQmxBase Error %ld: %s\n", error, errBuff);
654  return 0;
655 #endif
656 }
std::string itos(int)
Definition: Tools.cpp:46
int main(int argc, char *argv[])
std::string ftos(float)
Definition: Tools.cpp:53
void error(const char *)
def size
Definition: cat.py:38
int AO1(double)
const std::string & hostName()
Host name.
Definition: Server_NI6008.h:36
void setTimeout(double timeout=10.0)
char ** argv()
char** command line arguments including executable name as arg[0]; You may not modify them! ...
Definition: System.cpp:134
int AO(const char *, double[])
const std::string & accountName()
User login name.
Definition: Server_NI6008.h:85
def data(object, stream=None)
Definition: shell.py:150
const std::string & osVersion()
OS version.
Definition: Server_NI6008.h:61
int DI(const char *, unsigned char[])
virtual ~Server_NI6008()
Standard constructor.
void msgSvc(MsgLevel, std::string, std::string call=std::string(""))
void log(MsgLevel, std::string, std::string)
int AO0(double)
const std::string & osName()
OS name.
Definition: Server_NI6008.h:48
int AI(const char *, double[])
#define DAQmxErrChk(functionCall)
std::string logtime()
int send(std::string word)
std::vector< std::string > colors
struct sockaddr_in serv_addr cli_addr
void setAIRange(double min=-10., double max=10.)
void setAORange(double min=0., double max=5.)
long argc()
Number of arguments passed to the commandline (==numCmdLineArgs()); just to match argv call...
Definition: System.cpp:105
socklen_t clilen
char buffer[256]