FACT++  1.0
fad.cc
Go to the documentation of this file.
1 #include <iostream>
2 #include <string>
3 #include <boost/asio.hpp>
4 #include <boost/bind.hpp>
5 #include <boost/lexical_cast.hpp>
6 #include <boost/asio/deadline_timer.hpp>
7 #include <boost/enable_shared_from_this.hpp>
8 
9 using boost::lexical_cast;
10 
11 #include "Time.h"
12 #include "Converter.h"
13 
14 #include "HeadersFAD.h"
15 
16 #include "dis.hxx"
17 #include "Dim.h"
18 
19 using namespace std;
20 using namespace FAD;
21 
22 namespace ba = boost::asio;
23 namespace bs = boost::system;
24 namespace dummy = ba::placeholders;
25 
26 using boost::lexical_cast;
27 using ba::ip::tcp;
28 
29 class tcp_connection;
30 
31 class Trigger : public DimCommandHandler
32 {
34 
35  vector<tcp_connection*> vec;
36 
37 public:
38  Trigger() : fCmd("FAD/TRIGGER", "I:1", this)
39  {
40  }
41 
42  void Add(tcp_connection *ptr)
43  {
44  vec.push_back(ptr);
45  }
46 
48  {
49  vec.erase(find(vec.begin(), vec.end(), ptr));
50  }
51 
52  void commandHandler();
53 };
54 
55 // ------------------------------------------------------------------------
56 
57 class tcp_connection : public ba::ip::tcp::socket, public boost::enable_shared_from_this<tcp_connection>
58 {
59 public:
60  static Trigger fTrigger;
61 
62  const int fBoardId;
63 
64  double fStartTime;
65 
66  void AsyncRead(ba::mutable_buffers_1 buffers)
67  {
68  ba::async_read(*this, buffers,
69  boost::bind(&tcp_connection::HandleReceivedData, shared_from_this(),
70  dummy::error, dummy::bytes_transferred));
71  }
72 
73  void AsyncWrite(ba::ip::tcp::socket *socket, const ba::const_buffers_1 &buffers)
74  {
75  ba::async_write(*socket, buffers,
76  boost::bind(&tcp_connection::HandleSentData, shared_from_this(),
77  dummy::error, dummy::bytes_transferred));
78  }
79  void AsyncWait(ba::deadline_timer &timer, int seconds,
80  void (tcp_connection::*handler)(const bs::error_code&))// const
81  {
82  timer.expires_from_now(boost::posix_time::milliseconds(seconds));
83  timer.async_wait(boost::bind(handler, shared_from_this(), dummy::error));
84  }
85 
86  // The constructor is prvate to force the obtained pointer to be shared
87  tcp_connection(ba::io_service& ioservice, int boardid) : ba::ip::tcp::socket(ioservice),
88  fBoardId(boardid), fRamRoi(kNumChannels), fTriggerSendData(ioservice),
89  fTriggerEnabled(false)
90  {
91  fTrigger.Add(this);
92  }
93  void PostTrigger(uint32_t triggerid)
94  {
95  if (fTriggerEnabled)
96  get_io_service().post(boost::bind(&tcp_connection::SendData, this, triggerid));
97  }
98 
99  // Callback when writing was successfull or failed
100 #ifdef DEBUG_TX
101  void HandleSentData(const boost::system::error_code& error, size_t bytes_transferred)
102  {
103  cout << "Data sent[" << fBoardId << "]: (transmitted=" << bytes_transferred << ") rc=" << error.message() << " (" << error << ")" << endl;
104  fOutQueue.pop_front();
105  }
106 #else
107  void HandleSentData(const boost::system::error_code&, size_t)
108  {
109  fOutQueue.pop_front();
110  }
111 #endif
112 
113  vector<uint16_t> fBufCommand;
114 
115  vector<uint16_t> fCommand;
116 
117  FAD::EventHeader fHeader;
118  FAD::EventHeader fRam;
119  FAD::ChannelHeader fChHeader[kNumChannels];
120 
121  vector<uint16_t> fRamRoi;
122 
123  ba::deadline_timer fTriggerSendData;
124 
127 
128  int fSocket;
129 
130  deque<vector<uint16_t>> fOutQueue;
131 
132  void SendData(uint32_t triggerid)
133  {
134  if (fOutQueue.size()>3)
135  return;
136 
137  fHeader.fPackageLength = sizeof(EventHeader)/2+1;
138  fHeader.fEventCounter++;
139  fHeader.fTriggerCounter = triggerid;
140  fHeader.fTimeStamp = uint32_t((Time(Time::utc).UnixTime()-fStartTime)*10000);
141  fHeader.fFreqRefClock = 997+rand()/(RAND_MAX/7);
142 
143  /* Trigger ID
144 
145  * Byte[4]: Bit 0: ext1
146  * Byte[4]: Bit 1: ext2
147  * Byte[4]: Bit 2-7: n/40
148  * Byte[5]: Bit 0: LP_1
149  * Byte[5]: Bit 1: LP_2
150  * Byte[5]: Bit 2: Pedestal
151  * Byte[5]: Bit 3:
152  * Byte[5]: Bit 4:
153  * Byte[5]: Bit 5:
154  * Byte[5]: Bit 6:
155  * Byte[5]: Bit 7: TIM source
156 
157  */
158 
159  for (int i=0; i<FAD::kNumTemp; i++)
160  fHeader.fTempDrs[i] = (42.+fBoardId/40.+float(rand())/RAND_MAX*5)*16;
161 
162  // Header, channel header, end delimiter
163  size_t sz = sizeof(fHeader) + kNumChannels*sizeof(FAD::ChannelHeader) + 2;
164  // Data
165  for (int i=0; i<kNumChannels; i++)
166  sz += fChHeader[i].fRegionOfInterest*2;
167 
168  vector<uint16_t> evtbuf;
169  evtbuf.reserve(sz);
170 
171  for (int i=0; i<kNumChannels; i++)
172  {
173  fChHeader[i].fStartCell = int64_t(1023)*rand()/RAND_MAX;
174 
175  vector<int16_t> data(fChHeader[i].fRegionOfInterest, -1024+0x42+i/9+fHeader.fDac[1]/32);
176 
177  for (int ii=0; ii<fChHeader[i].fRegionOfInterest; ii++)
178  {
179  const int rel = ii;
180  const int abs = (ii+fChHeader[i].fStartCell)%fChHeader[i].fRegionOfInterest;
181 
182  data[rel] += 6.*rand()/RAND_MAX + 5*exp(-rel/10); // sigma=10
183  data[rel] += 15*sin(2*3.1415*abs/512); // sigma=10
184  }
185 
186  if (triggerid>0)
187  {
188  int p = 5.*rand()/RAND_MAX+ 20;
189  double rndm = 500.*rand()/RAND_MAX+500;
190  for (int ii=0; ii<fChHeader[i].fRegionOfInterest; ii++)
191  data[ii] += rndm*exp(-0.5*(ii-p)*(ii-p)/25); // sigma=10
192  }
193 
194  const vector<uint16_t> buf = fChHeader[i].HtoN();
195 
196  evtbuf.insert(evtbuf.end(), buf.begin(), buf.end());
197  evtbuf.insert(evtbuf.end(), data.begin(), data.end());
198 
199  fHeader.fPackageLength += sizeof(ChannelHeader)/2;
200  fHeader.fPackageLength += fChHeader[i].fRegionOfInterest;
201  }
202 
203  evtbuf.push_back(htons(FAD::kDelimiterEnd));
204 
205  const vector<uint16_t> h = fHeader.HtoN();
206 
207  evtbuf.insert(evtbuf.begin(), h.begin(), h.end());
208 
209  fOutQueue.push_back(evtbuf);
210 
211  if (fCommandSocket)
212  AsyncWrite(this, ba::buffer(ba::const_buffer(fOutQueue.back().data(), fOutQueue.back().size()*2)));
213  else
214  {
215  if (fSockets.size()==0)
216  return;
217 
218  fSocket++;
219  fSocket %= fSockets.size();
220 
221  AsyncWrite(fSockets[fSocket].get(), ba::buffer(ba::const_buffer(fOutQueue.back().data(), fOutQueue.back().size()*2)));
222  }
223  }
224 
225  void TriggerSendData(const boost::system::error_code &ec)
226  {
227  if (!is_open())
228  {
229  // For example: Here we could schedule a new accept if we
230  // would not want to allow two connections at the same time.
231  return;
232  }
233 
234  if (ec==ba::error::basic_errors::operation_aborted)
235  return;
236 
237  // Check whether the deadline has passed. We compare the deadline
238  // against the current time since a new asynchronous operation
239  // may have moved the deadline before this actor had a chance
240  // to run.
241  if (fTriggerSendData.expires_at() > ba::deadline_timer::traits_type::now())
242  return;
243 
244  // The deadline has passed.
245  if (fTriggerEnabled)
246  SendData(0);
247 
248  AsyncWait(fTriggerSendData, fHeader.fTriggerGeneratorPrescaler, &tcp_connection::TriggerSendData);
249  }
250 
251  void HandleReceivedData(const boost::system::error_code& error, size_t bytes_received)
252  {
253  // Do not schedule a new read if the connection failed.
254  if (bytes_received==0)
255  {
256  // Close the connection
257  close();
258  return;
259  }
260 
261  // No command received yet
262  if (fCommand.size()==0)
263  {
264  transform(fBufCommand.begin(), fBufCommand.begin()+bytes_received/2,
265  fBufCommand.begin(), ntohs);
266 
267  switch (fBufCommand[0])
268  {
269  case kCmdDrsEnable:
270  case kCmdDrsEnable+0x100:
271  fHeader.Enable(FAD::EventHeader::kDenable, fBufCommand[0]==kCmdDrsEnable);
272  cout << "-> DrsEnable " << fBoardId << " " << (fBufCommand[0]==kCmdDrsEnable) << endl;
273  break;
274 
275  case kCmdDwrite:
276  case kCmdDwrite+0x100:
277  fHeader.Enable(FAD::EventHeader::kDwrite, fBufCommand[0]==kCmdDwrite);
278  cout << "-> Dwrite " << fBoardId << " " << (fBufCommand[0]==kCmdDwrite) << endl;
279  break;
280 
281  case kCmdTriggerLine:
282  case kCmdTriggerLine+0x100:
283  cout << "-> Trigger line " << fBoardId << " " << (fBufCommand[0]==kCmdTriggerLine) << endl;
284  fTriggerEnabled = fBufCommand[0]==kCmdTriggerLine;
285  fHeader.Enable(FAD::EventHeader::kTriggerLine, fTriggerEnabled);
286  break;
287 
288  case kCmdSclk:
289  case kCmdSclk+0x100:
290  cout << "-> Sclk " << fBoardId << endl;
291  fHeader.Enable(FAD::EventHeader::kSpiSclk, fBufCommand[0]==kCmdSclk);
292  break;
293 
294  case kCmdSrclk:
295  case kCmdSrclk+0x100:
296  cout << "-> Srclk " << fBoardId << endl;
297  break;
298 
299  case kCmdRun:
300  case kCmdRun+0x100:
301  fStartTime = Time(Time::utc).UnixTime();
302  cout << "-> Run " << fBoardId << endl;
303  break;
304 
305  case kCmdBusyOff:
306  case kCmdBusyOff+0x100:
307  cout << "-> BusyOff " << fBoardId << " " << (fBufCommand[0]==kCmdBusyOff) << endl;
308  fHeader.Enable(FAD::EventHeader::kBusyOff, fBufCommand[0]==kCmdBusyOff);
309  break;
310 
311  case kCmdBusyOn:
312  case kCmdBusyOn+0x100:
313  cout << "-> BusyOn " << fBoardId << " " << (fBufCommand[0]==kCmdBusyOn) << endl;
314  fHeader.Enable(FAD::EventHeader::kBusyOn, fBufCommand[0]==kCmdBusyOn);
315  break;
316 
317  case kCmdSocket:
318  case kCmdSocket+0x100:
319  cout << "-> Socket " << fBoardId << " " << (fBufCommand[0]==kCmdSocket) << endl;
320  fCommandSocket = fBufCommand[0]==kCmdSocket;
321  fHeader.Enable(FAD::EventHeader::kSock17, !fCommandSocket);
322  break;
323 
324  case kCmdContTrigger:
325  case kCmdContTrigger+0x100:
326  if (fBufCommand[0]==kCmdContTrigger)
327  AsyncWait(fTriggerSendData, 0, &tcp_connection::TriggerSendData);
328  else
329  fTriggerSendData.cancel();
330  fHeader.Enable(FAD::EventHeader::kContTrigger, fBufCommand[0]==kCmdContTrigger);
331  cout << "-> ContTrig " << fBoardId << " " << (fBufCommand[0]==kCmdContTrigger) << endl;
332  break;
333 
335  cout << "-> ResetId " << fBoardId << endl;
336  fHeader.fEventCounter = 0;
337  break;
338 
339  case kCmdSingleTrigger:
340  cout << "-> Trigger " << fBoardId << endl;
341  SendData(0);
342  break;
343 
344  case kCmdWriteExecute:
345  cout << "-> Execute " << fBoardId << endl;
346  memcpy(fHeader.fDac, fRam.fDac, sizeof(fHeader.fDac));
347  for (int i=0; i<kNumChannels; i++)
348  fChHeader[i].fRegionOfInterest = fRamRoi[i];
349  fHeader.fRunNumber = fRam.fRunNumber;
350  break;
351 
353  fCommand = fBufCommand;
354  break;
355 
357  fCommand = fBufCommand;
358  break;
359 
360  default:
361  if (fBufCommand[0]>=kCmdWriteRoi && fBufCommand[0]<kCmdWriteRoi+kNumChannels)
362  {
363  fCommand.resize(2);
364  fCommand[0] = kCmdWriteRoi;
365  fCommand[1] = fBufCommand[0]-kCmdWriteRoi;
366  break;
367  }
368  if (fBufCommand[0]>= kCmdWriteDac && fBufCommand[0]<kCmdWriteDac+kNumDac)
369  {
370  fCommand.resize(2);
371  fCommand[0] = kCmdWriteDac;
372  fCommand[1] = fBufCommand[0]-kCmdWriteDac;
373  break;
374  }
375  if (fBufCommand[0]==kCmdWriteRate)
376  {
377  fCommand.resize(1);
378  fCommand[0] = kCmdWriteRate;
379  break;
380  }
381 
382  cout << "Received b=" << bytes_received << ": " << error.message() << " (" << error << ")" << endl;
383  cout << "Hex:" << Converter::GetHex<uint16_t>(&fBufCommand[0], bytes_received) << endl;
384  return;
385  }
386 
387  fBufCommand.resize(1);
388  AsyncRead(ba::buffer(fBufCommand));
389  return;
390  }
391 
392  transform(fBufCommand.begin(), fBufCommand.begin()+bytes_received/2,
393  fBufCommand.begin(), ntohs);
394 
395  switch (fCommand[0])
396  {
398  fRam.fRunNumber &= 0xffff;
399  fRam.fRunNumber |= fBufCommand[0]<<16;
400  cout << "-> Set RunNumber " << fBoardId << " MSW" << endl;
401  break;
403  fRam.fRunNumber &= 0xffff0000;
404  fRam.fRunNumber |= fBufCommand[0];
405  cout << "-> Set RunNumber " << fBoardId << " LSW" << endl;
406  break;
407  case kCmdWriteRoi:
408  cout << "-> Set " << fBoardId << " Roi[" << fCommand[1] << "]=" << fBufCommand[0] << endl;
409  //fChHeader[fCommand[1]].fRegionOfInterest = fBufCommand[0];
410  fRamRoi[fCommand[1]] = fBufCommand[0];
411  break;
412 
413  case kCmdWriteDac:
414  cout << "-> Set " << fBoardId << " Dac[" << fCommand[1] << "]=" << fBufCommand[0] << endl;
415  fRam.fDac[fCommand[1]] = fBufCommand[0];
416  break;
417 
418  case kCmdWriteRate:
419  cout << "-> Set " << fBoardId << " Rate =" << fBufCommand[0] << endl;
420  fHeader.fTriggerGeneratorPrescaler = fBufCommand[0];
421  break;
422  }
423 
424  fCommand.resize(0);
425 
426  fBufCommand.resize(1);
427  AsyncRead(ba::buffer(fBufCommand));
428  }
429 
430 public:
431  typedef boost::shared_ptr<tcp_connection> shared_ptr;
432 
433  static shared_ptr create(ba::io_service& io_service, int boardid)
434  {
435  return shared_ptr(new tcp_connection(io_service, boardid));
436  }
437 
438  void start()
439  {
440  // Ownership of buffer must be valid until Handler is called.
441 
442  fTriggerEnabled=false;
443  fCommandSocket=true;
444 
445  fHeader.fStartDelimiter = FAD::kDelimiterStart;
446  fHeader.fVersion = 0x104;
447  fHeader.fBoardId = (fBoardId%10) | ((fBoardId/10)<<8);
448  fHeader.fRunNumber = 0;
449  fHeader.fDNA = reinterpret_cast<uint64_t>(this);
450  fHeader.fTriggerGeneratorPrescaler = 100;
451  fHeader.fStatus = 0xf<<12 |
452  FAD::EventHeader::kDenable |
453  FAD::EventHeader::kDwrite |
454  FAD::EventHeader::kDcmLocked |
455  FAD::EventHeader::kDcmReady |
456  FAD::EventHeader::kSpiSclk;
457 
458 
459  fStartTime = Time(Time::utc).UnixTime();
460 
461  for (int i=0; i<kNumChannels; i++)
462  {
463  fChHeader[i].fId = (i%9) | ((i/9)<<4);
464  fChHeader[i].fRegionOfInterest = 0;
465  }
466 
467  // Emit something to be written to the socket
468  fBufCommand.resize(1);
469  AsyncRead(ba::buffer(fBufCommand));
470 
471 // AsyncWait(fTriggerDynData, 1, &tcp_connection::SendDynData);
472 
473 // AsyncWrite(ba::buffer(ba::const_buffer(&fHeader, sizeof(FTM::Header))));
474 // AsyncWait(deadline_, 3, &tcp_connection::check_deadline);
475 
476  }
477 
478  vector<boost::shared_ptr<ba::ip::tcp::socket>> fSockets;
479 
481  {
482  fTrigger.Remove(this);
483  fSockets.clear();
484  }
485 
486  void handle_accept(boost::shared_ptr<ba::ip::tcp::socket> socket, int port, const boost::system::error_code&/* error*/)
487  {
488  cout << this << " Added one socket[" << fBoardId << "] " << socket->remote_endpoint().address().to_v4().to_string();
489  cout << ":"<< port << endl;
490  fSockets.push_back(socket);
491  }
492 };
493 
495 
497 {
498  if (!getCommand())
499  return;
500 
501  for (vector<tcp_connection*>::iterator it=vec.begin();
502  it!=vec.end(); it++)
503  (*it)->PostTrigger(getCommand()->getInt());
504 }
505 
506 
508 {
509  tcp::acceptor acc0;
510  tcp::acceptor acc1;
511  tcp::acceptor acc2;
512  tcp::acceptor acc3;
513  tcp::acceptor acc4;
514  tcp::acceptor acc5;
515  tcp::acceptor acc6;
516  tcp::acceptor acc7;
517 
518  int fBoardId;
519 
520 public:
521  tcp_server(ba::io_service& ioservice, int port, int board) :
522  acc0(ioservice, tcp::endpoint(tcp::v4(), port)),
523  acc1(ioservice, tcp::endpoint(tcp::v4(), port+1)),
524  acc2(ioservice, tcp::endpoint(tcp::v4(), port+2)),
525  acc3(ioservice, tcp::endpoint(tcp::v4(), port+3)),
526  acc4(ioservice, tcp::endpoint(tcp::v4(), port+4)),
527  acc5(ioservice, tcp::endpoint(tcp::v4(), port+5)),
528  acc6(ioservice, tcp::endpoint(tcp::v4(), port+6)),
529  acc7(ioservice, tcp::endpoint(tcp::v4(), port+7)),
530  fBoardId(board)
531  {
532  // We could start listening for more than one connection
533  // here, but since there is only one handler executed each time
534  // it would not make sense. Before one handle_accept is not
535  // finished no new handle_accept will be called.
536  // Workround: Start a new thread in handle_accept
537  start_accept();
538  }
539 
540 private:
541  void start_accept(tcp_connection::shared_ptr dest, tcp::acceptor &acc)
542  {
543  boost::shared_ptr<ba::ip::tcp::socket> connection =
544  boost::shared_ptr<ba::ip::tcp::socket>(new ba::ip::tcp::socket(acc.get_io_service()));
545 
546  acc.async_accept(*connection,
547  boost::bind(&tcp_connection::handle_accept,
548  dest, connection,
549  acc.local_endpoint().port(),
550  ba::placeholders::error));
551  }
552 
554  {
555  cout << "Start accept[" << fBoardId << "] " << acc0.local_endpoint().port() << "..." << flush;
556  tcp_connection::shared_ptr new_connection = tcp_connection::create(/*acceptor_.*/acc0.get_io_service(), fBoardId);
557 
558  cout << new_connection.get() << " ";
559 
560  // This will accept a connection without blocking
561  acc0.async_accept(*new_connection,
562  boost::bind(&tcp_server::handle_accept,
563  this,
564  new_connection,
565  ba::placeholders::error));
566 
567  start_accept(new_connection, acc1);
568  start_accept(new_connection, acc2);
569  start_accept(new_connection, acc3);
570  start_accept(new_connection, acc4);
571  start_accept(new_connection, acc5);
572  start_accept(new_connection, acc6);
573  start_accept(new_connection, acc7);
574 
575  cout << "start-done." << endl;
576  }
577 
578  void handle_accept(tcp_connection::shared_ptr new_connection, const boost::system::error_code& error)
579  {
580  // The connection has been accepted and is now ready to use
581 
582  // not installing a new handler will stop run()
583  cout << new_connection.get() << " Handle accept[" << fBoardId << "]["<<new_connection->fBoardId<<"]..." << flush;
584  if (!error)
585  {
586  new_connection->start();
587 
588  // The is now an open connection/server (tcp_connection)
589  // we immediatly schedule another connection
590  // This allowed two client-connection at the same time
591  start_accept();
592  }
593  cout << "handle-done." << endl;
594  }
595 };
596 
597 #include "Configuration.h"
598 
600 {
601  const string n = conf.GetName()+".log";
602 
603  po::options_description config("Program options");
604  config.add_options()
605  ("dns", var<string>("localhost"), "Dim nameserver host name (Overwites DIM_DNS_NODE environment variable)")
606  ("port,p", var<uint16_t>(4000), "")
607  ("num,n", var<uint16_t>(40), "")
608  ;
609 
610  po::positional_options_description p;
611  p.add("port", 1); // The first positional options
612  p.add("num", 1); // The second positional options
613 
614  conf.AddEnv("dns", "DIM_DNS_NODE");
615 
616  conf.AddOptions(config);
617  conf.SetArgumentPositions(p);
618 }
619 
620 int main(int argc, const char **argv)
621 {
622  ::Configuration conf(argv[0]);
623 
624  SetupConfiguration(conf);
625 
626  po::variables_map vm;
627  try
628  {
629  vm = conf.Parse(argc, argv);
630  }
631 #if BOOST_VERSION > 104000
632  catch (po::multiple_occurrences &e)
633  {
634  cerr << "Program options invalid due to: " << e.what() << " of '" << e.get_option_name() << "'." << endl;
635  return -1;
636  }
637 #endif
638  catch (exception& e)
639  {
640  cerr << "Program options invalid due to: " << e.what() << endl;
641  return -1;
642  }
643 
644  if (conf.HasVersion() || conf.HasPrint() || conf.HasHelp())
645  return -1;
646 
647  Dim::Setup(conf.Get<string>("dns"));
648 
649  DimServer::start("FAD");
650 
651  //try
652  {
653  ba::io_service io_service;
654 
655  const uint16_t n = conf.Get<uint16_t>("num");
656  uint16_t port = conf.Get<uint16_t>("port");
657 
658  vector<shared_ptr<tcp_server>> servers;
659 
660  for (int i=0; i<n; i++)
661  {
662  shared_ptr<tcp_server> server(new tcp_server(io_service, port, i));
663  servers.push_back(server);
664 
665  port += 8;
666  }
667 
668  // ba::add_service(io_service, &server);
669  // server.add_service(...);
670  //cout << "Run..." << flush;
671 
672  // Calling run() from a single thread ensures no concurrent access
673  // of the handler which are called!!!
674  io_service.run();
675 
676  //cout << "end." << endl;
677  }
678  /*catch (std::exception& e)
679  {
680  std::cerr << e.what() << std::endl;
681  }*/
682 
683  return 0;
684 }
685 /* ====================== Buffers ===========================
686 
687 char d1[128]; ba::buffer(d1));
688 std::vector<char> d2(128); ba::buffer(d2);
689 boost::array<char, 128> d3; by::buffer(d3);
690 
691 // --------------------------------
692 char d1[128];
693 std::vector<char> d2(128);
694 boost::array<char, 128> d3;
695 
696 boost::array<mutable_buffer, 3> bufs1 = {
697  ba::buffer(d1),
698  ba::buffer(d2),
699  ba::buffer(d3) };
700 sock.read(bufs1);
701 
702 std::vector<const_buffer> bufs2;
703 bufs2.push_back(boost::asio::buffer(d1));
704 bufs2.push_back(boost::asio::buffer(d2));
705 bufs2.push_back(boost::asio::buffer(d3));
706 sock.write(bufs2);
707 
708 
709 // ======================= Read functions =========================
710 
711 ba::async_read_until --> delimiter
712 
713 streambuf buf; // Ensure validity until handler!
714 by::async_read(s, buf, ....);
715 
716 ba::async_read(s, ba:buffer(data, size), handler);
717  // Single buffer
718  boost::asio::async_read(s,
719  ba::buffer(data, size),
720  compl-func --> ba::transfer_at_least(32),
721  handler);
722 
723  // Multiple buffers
724 boost::asio::async_read(s, buffers,
725  compl-func --> boost::asio::transfer_all(),
726  handler);
727  */
728 
729 // ================= Others ===============================
730 
731  /*
732  strand Provides serialised handler execution.
733  work Class to inform the io_service when it has work to do.
734 
735 
736 io_service::
737 dispatch Request the io_service to invoke the given handler.
738 poll Run the io_service's event processing loop to execute ready
739  handlers.
740 poll_one Run the io_service's event processing loop to execute one ready
741  handler.
742 post Request the io_service to invoke the given handler and return
743  immediately.
744 reset Reset the io_service in preparation for a subsequent run()
745  invocation.
746 run Run the io_service's event processing loop.
747 run_one Run the io_service's event processing loop to execute at most
748  one handler.
749 stop Stop the io_service's event processing loop.
750 wrap Create a new handler that automatically dispatches the wrapped
751  handler on the io_service.
752 
753 strand:: The io_service::strand class provides the ability to
754  post and dispatch handlers with the guarantee that none
755  of those handlers will execute concurrently.
756 
757 dispatch Request the strand to invoke the given handler.
758 get_io_service Get the io_service associated with the strand.
759 post Request the strand to invoke the given handler and return
760  immediately.
761 wrap Create a new handler that automatically dispatches the
762  wrapped handler on the strand.
763 
764 work:: The work class is used to inform the io_service when
765  work starts and finishes. This ensures that the io_service's run() function will not exit while work is underway, and that it does exit when there is no unfinished work remaining.
766 get_io_service Get the io_service associated with the work.
767 work Constructor notifies the io_service that work is starting.
768 
769 */
770 
771 
vector< uint16_t > fCommand
Definition: fad.cc:115
uint16_t fRegionOfInterest
Definition: HeadersFAD.h:95
tcp::acceptor acc5
Definition: fad.cc:514
tcp::acceptor acc6
Definition: fad.cc:515
tcp::acceptor acc4
Definition: fad.cc:513
void TriggerSendData(const boost::system::error_code &ec)
Definition: fad.cc:225
static Trigger fTrigger
Definition: fad.cc:60
Trigger()
Definition: fad.cc:38
void start_accept()
Definition: fad.cc:553
void AsyncWait(ba::deadline_timer &timer, int seconds, void(tcp_connection::*handler)(const bs::error_code &))
Definition: fad.cc:79
ba::deadline_timer fTriggerSendData
Definition: fad.cc:123
void SendData()
Definition: fsc.cc:71
int i
Definition: db_dim_client.c:21
Initialize with UTC.
Definition: Time.h:52
const int fBoardId
Definition: fad.cc:62
Adds some functionality to boost::posix_time::ptime for our needs.
Definition: Time.h:30
T Get(const std::string &var)
void AsyncRead(ba::mutable_buffers_1 buffers)
Definition: fad.cc:66
uint16_t fBoardId
Definition: HeadersFAD.h:182
void SendData(uint32_t triggerid)
Definition: fad.cc:132
void HandleReceivedData(const boost::system::error_code &error, size_t bytes_received)
Definition: fad.cc:251
STL namespace.
void handle_accept(boost::shared_ptr< ba::ip::tcp::socket > socket, int port, const boost::system::error_code &)
Definition: fad.cc:486
tcp_server(ba::io_service &ioservice, int port, int board)
Definition: fad.cc:521
void AddEnv(const std::string &conf, const std::string &env)
bool fCommandSocket
Definition: fad.cc:126
void SetArgumentPositions(const po::positional_options_description &desc)
void Add(tcp_connection *ptr)
Definition: fad.cc:42
void commandHandler()
Definition: fad.cc:496
void Setup(const std::string &dns="", const std::string &host="")
Definition: DimSetup.cc:160
void handle_accept(tcp_connection::shared_ptr new_connection, const boost::system::error_code &error)
Definition: fad.cc:578
tcp::acceptor acc1
Definition: fad.cc:510
tcp::acceptor acc0
Definition: fad.cc:509
double fStartTime
Definition: fad.cc:64
~tcp_connection()
Definition: fad.cc:480
boost::shared_ptr< tcp_connection > shared_ptr
Definition: fad.cc:431
void start()
Definition: fad.cc:438
void AddOptions(const po::options_description &opt, bool visible=true)
Definition: Configuration.h:92
double UnixTime() const
Definition: Time.cc:195
void PostTrigger(uint32_t triggerid)
Definition: fad.cc:93
int fBoardId
Definition: fad.cc:518
Commandline parsing, resource file parsing and database access.
Definition: Configuration.h:9
bool fTriggerEnabled
Definition: fad.cc:125
int buffer[BUFFSIZE]
Definition: db_dim_client.c:14
void AsyncWrite(ba::ip::tcp::socket *socket, const ba::const_buffers_1 &buffers)
Definition: fad.cc:73
tcp_connection(ba::io_service &ioservice, int boardid)
Definition: fad.cc:87
vector< boost::shared_ptr< ba::ip::tcp::socket > > fSockets
Definition: fad.cc:478
static void start()
Definition: discpp.cxx:512
float data[4 *1440]
FAD::EventHeader fHeader
Definition: fad.cc:117
deque< vector< uint16_t > > fOutQueue
Definition: fad.cc:130
tcp::acceptor acc7
Definition: fad.cc:516
FAD::EventHeader fRam
Definition: fad.cc:118
static void handler(int conn_id, char *packet, int size, int status)
Definition: webServer.c:635
void Remove(tcp_connection *ptr)
Definition: fad.cc:47
void start_accept(tcp_connection::shared_ptr dest, tcp::acceptor &acc)
Definition: fad.cc:541
int main(int argc, const char **argv)
Definition: fad.cc:620
const po::variables_map & Parse(int argc, const char **argv, const std::function< void()> &func=std::function< void()>())
vector< uint16_t > fBufCommand
Definition: fad.cc:113
DimCommand fCmd
Definition: fad.cc:33
vector< tcp_connection * > vec
Definition: fad.cc:35
void SetupConfiguration(::Configuration &conf)
Definition: fad.cc:599
tcp::acceptor acc3
Definition: fad.cc:512
vector< uint16_t > fRamRoi
Definition: fad.cc:121
Definition: fad.cc:31
tcp::acceptor acc2
Definition: fad.cc:511
void HandleSentData(const boost::system::error_code &, size_t)
Definition: fad.cc:107
static shared_ptr create(ba::io_service &io_service, int boardid)
Definition: fad.cc:433
const std::string & GetName() const
int fSocket
Definition: fad.cc:128