Belle II Software  release-08-01-10
dummy_data_src.cc
1 /**************************************************************************
2  * basf2 (Belle II Analysis Software Framework) *
3  * Author: The Belle II Collaboration *
4  * *
5  * See git log for contributors and copyright holders. *
6  * This file is licensed under LGPL-3.0, see LICENSE.md. *
7  **************************************************************************/
8 #include <iostream>
9 #include <vector>
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <netinet/in.h>
13 #include <sys/socket.h>
14 #include <sys/time.h>
15 #include <string.h>
16 #include <unistd.h>
17 #include <limits.h>
18 
20 // Parameter for data-contents
22 //#define REDUCED_DATA
23 #define CRC_ON
24 
25 #define LISTENQ 1
26 #define SERVER
27 
28 
29 #define NW_SEND_HEADER 6
30 #define NW_SEND_TRAILER 2
31 #define NW_RAW_HEADER 12
32 #define NW_RAW_TRAILER 2
33 
34 
35 
36 #ifdef REDUCED_DATA
37 #define NW_COPPER_HEADER 0
38 #define NW_B2L_HEADER 2
39 #define NW_B2L_TRAILER 1
40 #define NW_COPPER_TRAILER 0
41 #else
42 #define NW_COPPER_HEADER 13
43 #define NW_B2L_HEADER 6
44 #define NW_B2L_TRAILER 3
45 #define NW_COPPER_TRAILER 3
46 #endif
47 
48 using namespace std;
49 
50 unsigned short CalcCRC16LittleEndian(unsigned short crc16, const int buf[], int nwords)
51 {
52 
53  if (nwords < 0) {
54  char err_buf[500];
55  sprintf(err_buf, "nwords value(%d) is invalid. Cannot calculate CRC16. Exiting...\n %s %s %d\n",
56  nwords, __FILE__, __PRETTY_FUNCTION__, __LINE__);
57  printf("%s", err_buf); fflush(stdout);
58  string err_str = err_buf;
59  throw (err_str);
60  }
61 
62  const unsigned short CRC16Table0x1021[ 256 ] = {
63  0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7,
64  0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF,
65  0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6,
66  0x9339, 0x8318, 0xB37B, 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE,
67  0x2462, 0x3443, 0x0420, 0x1401, 0x64E6, 0x74C7, 0x44A4, 0x5485,
68  0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE, 0xF5CF, 0xC5AC, 0xD58D,
69  0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6, 0x5695, 0x46B4,
70  0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF, 0xE7FE, 0xD79D, 0xC7BC,
71 
72  0x48C4, 0x58E5, 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823,
73  0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969, 0xA90A, 0xB92B,
74  0x5AF5, 0x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0x0A50, 0x3A33, 0x2A12,
75  0xDBFD, 0xCBDC, 0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A,
76  0x6CA6, 0x7C87, 0x4CE4, 0x5CC5, 0x2C22, 0x3C03, 0x0C60, 0x1C41,
77  0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD, 0xAD2A, 0xBD0B, 0x8D68, 0x9D49,
78  0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13, 0x2E32, 0x1E51, 0x0E70,
79  0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A, 0x9F59, 0x8F78,
80 
81  0x9188, 0x81A9, 0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E, 0xE16F,
82  0x1080, 0x00A1, 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 0x6067,
83  0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E,
84  0x02B1, 0x1290, 0x22F3, 0x32D2, 0x4235, 0x5214, 0x6277, 0x7256,
85  0xB5EA, 0xA5CB, 0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D,
86  0x34E2, 0x24C3, 0x14A0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
87  0xA7DB, 0xB7FA, 0x8799, 0x97B8, 0xE75F, 0xF77E, 0xC71D, 0xD73C,
88  0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657, 0x7676, 0x4615, 0x5634,
89 
90  0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9, 0xB98A, 0xA9AB,
91  0x5844, 0x4865, 0x7806, 0x6827, 0x18C0, 0x08E1, 0x3882, 0x28A3,
92  0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A,
93  0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0, 0x2AB3, 0x3A92,
94  0xFD2E, 0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9,
95  0x7C26, 0x6C07, 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1,
96  0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8,
97  0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0
98  };
99 
100  int cnt = 0, nints = 0;
101  // printf("### %.8x %.4x\n", buf[ 0 ], crc16);
102  while (nwords != 0) {
103 
104  unsigned char temp_buf = *((unsigned char*)(buf + nints) + (-(cnt % 4) + 3));
105  crc16 = CRC16Table0x1021[(crc16 >> (16 - CHAR_BIT)) ^ temp_buf ] ^ (crc16 << CHAR_BIT);
106  // printf("%.2x %.4x\n", temp_buf, crc16);
107  if ((cnt % 4) == 3) {
108  nwords--;
109  nints++;
110  // printf("### %.8x\n", buf[ nints ] );
111  }
112 
113  cnt++;
114  }
115 
116 
117  return crc16;
118 
119 }
120 
121 
122 double getTimeSec()
123 {
124  struct timeval t;
125  gettimeofday(&t, NULL);
126  return (t.tv_sec + t.tv_usec * 1.e-6 - 1417570000.);
127 }
128 
129 int fillDataContents(int* buf, int nwords_per_fee, unsigned int node_id, int ncpr, int nhslb, int run)
130 {
131  int nwords = NW_SEND_HEADER + NW_SEND_TRAILER +
132  ncpr * (NW_RAW_HEADER + NW_COPPER_HEADER +
133  (NW_B2L_HEADER + NW_B2L_TRAILER + nwords_per_fee) * nhslb
134  + NW_COPPER_TRAILER + NW_RAW_TRAILER);
135 
136 
137  // Send Header
138  int offset = 0;
139  buf[ offset + 0 ] = nwords;
140  buf[ offset + 1 ] = 6;
141  buf[ offset + 2 ] = (1 << 16) | ncpr;
142  unsigned int exp_run = run << 8;
143  buf[ offset + 3 ] = exp_run;
144  buf[ offset + 5 ] = node_id;
145  offset += 6;
146 
147 
148 
149  for (int k = 0; k < ncpr; k++) {
150  int top_pos = offset;
151  //
152  // RawHeader
153  //
154  int cpr_nwords = NW_RAW_HEADER + NW_COPPER_HEADER +
155  (NW_B2L_HEADER + NW_B2L_TRAILER + nwords_per_fee) * nhslb
156  + NW_COPPER_TRAILER + NW_RAW_TRAILER;
157  int finesse_nwords = nwords_per_fee + NW_B2L_HEADER + NW_B2L_TRAILER;
158  unsigned int ctime = 0x12345601;
159  unsigned int utime = 0x98765432;
160 
161 
162  buf[ offset + 0 ] = cpr_nwords;
163 #ifdef REDUCED_DATA
164  buf[ offset + 1 ] = 0x7f7f020c;
165 #else
166  buf[ offset + 1 ] = 0x7f7f820c;
167 #endif
168  buf[ offset + 2 ] = exp_run;
169  printf("run_no %d\n", exp_run); fflush(stdout);
170  buf[ offset + 4 ] = ctime;
171  buf[ offset + 5 ] = utime;
172  buf[ offset + 6 ] = node_id + k;
173  buf[ offset + 7 ] = 0x34567890;
174  buf[ offset + 8 ] = NW_RAW_HEADER + NW_COPPER_HEADER;
175  buf[ offset + 9 ] = buf[ offset + 8 ] + finesse_nwords;
176  if (nhslb > 1) {
177  buf[ offset + 10 ] = buf[ offset + 9 ] + finesse_nwords;
178  } else {
179  buf[ offset + 10 ] = buf[ offset + 9 ];
180  }
181  if (nhslb > 2) {
182  buf[ offset + 11 ] = buf[ offset + 10 ] + finesse_nwords;
183  } else {
184  buf[ offset + 11 ] = buf[ offset + 10 ];
185  }
186  offset += 12;
187 
188 #ifdef REDUCED_DATA
189 #else
190  int top_pos_cpr = offset;
191 
192  // COPPER header
193  buf[ offset + 0 ] = 0x7fff0008;
194  buf[ offset + 2 ] = 0;
195  buf[ offset + 3 ] = 0;
196  buf[ offset + 4 ] = 0;
197  buf[ offset + 5 ] = 0;
198  buf[ offset + 6 ] = 0;
199  buf[ offset + 7 ] = 0xfffffafa;
200  buf[ offset + 8 ] = cpr_nwords - (NW_RAW_HEADER + 7 + 2 + NW_RAW_TRAILER);
201  buf[ offset + 9 ] = finesse_nwords;
202 
203  if (nhslb > 1) {
204  buf[ offset + 10 ] = finesse_nwords;
205  if (nhslb > 2) {
206  buf[ offset + 11 ] = finesse_nwords;
207  if (nhslb > 3) {
208  buf[ offset + 12 ] = finesse_nwords;
209  } else {
210  buf[ offset + 12 ] = 0;
211  }
212  } else {
213  buf[ offset + 11 ] = 0;
214  buf[ offset + 12 ] = 0;
215  }
216  } else {
217  buf[ offset + 10 ] = 0;
218  buf[ offset + 11 ] = 0;
219  buf[ offset + 12 ] = 0;
220  }
221 
222 
223 
224  offset += 13;
225 #endif
226 
227  for (int i = 0; i < nhslb ; i++) {
228 #ifdef REDUCED_DATA
229  buf[ offset + 0 ] = 0xffaa0000;
230  buf[ offset + 1 ] = ctime;
231  offset += 2;
232 #else
233  buf[ offset + 0 ] = 0xffaa0000;
234  buf[ offset + 1 ] = ctime;
235  buf[ offset + 3 ] = utime;
236  buf[ offset + 4 ] = exp_run;
237  buf[ offset + 5 ] = ctime;
238  offset += 6;
239 #endif
240 
241  for (int j = offset; j < offset + nwords_per_fee; j++) {
242  buf[ j ] = rand();
243  }
244  offset += nwords_per_fee;
245 #ifdef REDUCED_DATA
246  buf[ offset ] = 0;
247  offset += 1;
248 #else
249  buf[ offset ] = ctime;
250  buf[ offset + 1 ] = 0;
251  buf[ offset + 2 ] = 0xff550000;
252  offset += 3;
253 #endif
254  }
255 
256 #ifdef REDUCED_DATA
257 #else
258  // COPPER trailer/Raw Trailer
259  buf[ offset ] = 0xfffff5f5;
260  buf[ offset + 1 ] = buf[ top_pos_cpr ];
261  for (int j = top_pos_cpr + 1; j < offset + 1; j++) {
262  buf[ offset + 1 ] ^= buf[ j ];
263  }
264  buf[ offset + 2 ] = 0x7fff0009;
265  offset += 3;
266 #endif
267  buf[ offset ] = buf[ top_pos ];
268  for (int j = top_pos + 1; j < offset; j++) {
269  buf[ offset ] ^= buf[ j ];
270  }
271  buf[ offset + 1 ] = 0x7fff0006;
272  offset += 2;
273  }
274 
275  // Send trailer
276  buf[ offset ] = 0;
277  buf[ offset + 1 ] = 0x7fff0000;
278  offset += 2;
279 
280 
281 
282  return offset;
283 }
284 
285 
286 
287 inline void addEvent(int* buf, int nwords_per_fee, unsigned int event, int ncpr, int nhslb)
288 //inline void addEvent(int* buf, int nwords, unsigned int event)
289 {
290  int offset = 0;
291  buf[ offset + 4 ] = event;
292  offset += NW_SEND_HEADER;
293 
294  for (int k = 0; k < ncpr; k++) {
295  int nwords = buf[ offset ];
296  int posback_xorchksum = 2;
297  int pos_xorchksum = offset + nwords - posback_xorchksum;
298  if (buf[ offset + 4 ] != 0x12345601) {
299  printf("[FATAL] data-production error 2 0x%.x", buf[ offset + 4 ]);
300  fflush(stdout);
301  exit(1);
302  }
303  // RawHeader
304  buf[ pos_xorchksum ] ^= buf[ offset + 3];
305  buf[ offset + 3] = event;
306  buf[ pos_xorchksum ] ^= buf[ offset + 3];
307 
308 #ifdef REDUCED_DATA
309  offset += NW_RAW_HEADER + NW_COPPER_HEADER +
310  nhslb * (NW_B2L_HEADER + nwords_per_fee + NW_B2L_TRAILER)
311  + NW_COPPER_TRAILER + NW_RAW_TRAILER;
312 #else
313  int pos_xorchksum_cpr = offset + nwords - 4;
314  buf[ pos_xorchksum ] ^= buf[ pos_xorchksum_cpr ];
315 
316  // COPPER header
317  offset += NW_RAW_HEADER;
318 
319  buf[ pos_xorchksum ] ^= buf[ offset + 1];
320  buf[ pos_xorchksum_cpr ] ^= buf[ offset + 1];
321  buf[ offset + 1 ] = event;
322  buf[ pos_xorchksum ] ^= buf[ offset + 1];
323  buf[ pos_xorchksum_cpr ] ^= buf[ offset + 1];
324  offset += NW_COPPER_HEADER;
325 
326  for (int i = 0; i < nhslb ; i++) {
327  if ((buf[ offset ] & 0xffff0000) != 0xffaa0000) {
328  printf("[FATAL] data-production error 3 : 0x%.x hslb %d cpr %d\n", buf[ offset ], i, k);
329  fflush(stdout);
330  exit(1);
331  }
332 
333  buf[ pos_xorchksum ] ^= buf[ offset + 0];
334  buf[ pos_xorchksum_cpr ] ^= buf[ offset + 0];
335  buf[ offset + 0 ] = 0xffaa0000 + (event & 0xffff);
336  buf[ pos_xorchksum ] ^= buf[ offset + 0];
337  buf[ pos_xorchksum_cpr ] ^= buf[ offset + 0];
338 
339  buf[ pos_xorchksum ] ^= buf[ offset + 2];
340  buf[ pos_xorchksum_cpr ] ^= buf[ offset + 2];
341  buf[ offset + 2 ] = event;
342  buf[ pos_xorchksum ] ^= buf[ offset + 2];
343  buf[ pos_xorchksum_cpr ] ^= buf[ offset + 2];
344 
345 #ifdef CRC_ON
346  int* crc_buf = buf + offset + 1; // 1 => size of HSLB B2L header
347  int crc_nwords = nwords_per_fee + 5; // 5 => size of FEE B2L header
348  unsigned short temp_crc16 = CalcCRC16LittleEndian(0xffff, crc_buf, crc_nwords);
349  buf[ pos_xorchksum ] ^= buf[ offset + NW_B2L_HEADER + nwords_per_fee + 1 ];
350  buf[ pos_xorchksum_cpr ] ^= buf[ offset + NW_B2L_HEADER + nwords_per_fee + 1 ];
351  buf[ offset + NW_B2L_HEADER + nwords_per_fee + 1 ] = ((event & 0x0000ffff) << 16) | temp_crc16;
352  // buf[ offset + NW_B2L_HEADER + nwords_per_fee + 1 ] = (unsigned int)temp_crc16;
353  buf[ pos_xorchksum ] ^= buf[ offset + NW_B2L_HEADER + nwords_per_fee + 1 ];
354  buf[ pos_xorchksum_cpr ] ^= buf[ offset + NW_B2L_HEADER + nwords_per_fee + 1 ];
355  // printf("NUM POS %d %.8x %.4x\n", offset + NW_B2L_HEADER + nwords_per_fee + 1,buf[ offset + NW_B2L_HEADER + nwords_per_fee + 1 ], temp_crc16 );
356 
357 #endif
358  offset += NW_B2L_HEADER + nwords_per_fee + NW_B2L_TRAILER;
359  }
360 
361  offset += NW_COPPER_TRAILER + NW_RAW_TRAILER;
362 
363  buf[ pos_xorchksum ] ^= buf[ pos_xorchksum_cpr ];
364 
365 #endif
366 
367  }
368 
369 }
370 
371 
372 int main(int argc, char** argv)
373 {
374 
375  printf("###################################################\n");
376 #ifdef REDUCED_DATA
377  printf("# Data after reduction (#define REDUCED_DATA) #\n");
378 #else
379  printf("# Data before reduction (//#define REDUCED_DATA) #\n");
380 #endif
381  printf("###################################################\n");
382 
383 #ifdef SERVER
384  if (argc != 6) {
385  printf("Usage : %s <node ID> <run#> <nwords of det. buf per FEE> <# of CPR per COPPER> <# of HSLBs>\n", argv[ 0 ]);
386  exit(1);
387  }
388 #else
389  if (argc != 8) {
390  printf("Usage : %s <node ID> <run#> <nwords of det. buf per FEE> <# of CPR per COPPER> <# of HSLBs> <ropc hostname> <ropc port> argc %d\n",
391  argv[ 0 ], argc);
392  exit(1);
393  }
394 #endif
395 
396  unsigned int node_id = 0;
397  sscanf(argv[1], "0x%x", &node_id);
398 
399 
400  int run_no = atoi(argv[2]);
401 
402 
403  int nwords_per_fee = atoi(argv[3]);
404  int ncpr = atoi(argv[4]);
405  int nhslb = atoi(argv[5]);
406 
407  int listenfd, connfd;
408  struct sockaddr_in servaddr;
409  int total_words = NW_SEND_HEADER + NW_SEND_TRAILER +
410  ncpr * (NW_RAW_HEADER + NW_COPPER_HEADER + (NW_B2L_HEADER + NW_B2L_TRAILER + nwords_per_fee) * nhslb + NW_COPPER_TRAILER +
411  NW_RAW_TRAILER);
412  printf("TET %d %d %d %d %d\n ", NW_SEND_HEADER + NW_SEND_TRAILER, ncpr,
413  NW_RAW_HEADER + NW_COPPER_HEADER, (NW_B2L_HEADER + NW_B2L_TRAILER + nwords_per_fee) * nhslb, NW_COPPER_TRAILER + NW_RAW_TRAILER);
414 
415  vector<int> buff(total_words);
416 
417  //
418  // Prepare header
419  //
420 
421  int temp_ret = fillDataContents(buff.data(), nwords_per_fee, node_id, ncpr, nhslb, run_no);
422  if (temp_ret != total_words) {
423  printf("[FATAL] data-production error %d %d\n", total_words, temp_ret);
424  fflush(stdout);
425  exit(1);
426  }
427 
428 
429 #ifdef SERVER
430  listenfd = socket(AF_INET, SOCK_STREAM, 0);
431  memset(&servaddr, 0, sizeof(servaddr));
432  servaddr.sin_family = AF_INET;
433  servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
434  servaddr.sin_port = htons(30000);
435 
436  int flags = 1;
437  int ret = setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &flags, (socklen_t)sizeof(flags));
438  if (ret < 0) {
439  perror("Failed to set REUSEADDR");
440  }
441 
442  bind(listenfd, (struct sockaddr*)&servaddr, sizeof(servaddr));
443 
444  listen(listenfd, LISTENQ);
445  printf("Accepting..."); fflush(stdout);
446  connfd = accept(listenfd, (struct sockaddr*) NULL, NULL);
447  printf("Done."); fflush(stdout);
448 #else
449 
450  // if( argc != 3 ){
451  // printf("Usage : %s <IPaddress> <port>\n", argv[0]);
452  // exit(1);
453  // }
454 
455  if ((connfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
456  perror("[FATAL] socket error");
457  exit(1);
458  }
459 
460  memset(&servaddr, 0, sizeof(servaddr));
461  servaddr.sin_family = AF_INET;
462  servaddr.sin_port = htons(atoi(argv[7]));
463  if (inet_pton(AF_INET, argv[6], &servaddr.sin_addr) <= 0) {
464  perror("[FATAL] inetpton error");
465  exit(1);
466  }
467 
468  while (true) {
469  if (connect(connfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) < 0) {
470  perror("Failed to connect");
471  continue;
472  }
473  sleep(1);
474  break;
475  }
476 
477 
478 #endif
479 
480  printf("Connection Accepted\n"); fflush(stdout);
481 
482  double init_time = getTimeSec();
483  double prev_time = init_time;
484 
485  unsigned long long int cnt = 0;
486  unsigned long long int prev_cnt = 0;
487  unsigned long long int start_cnt = 300000;
488  for (;;) {
489  // addEvent(buff, total_words, cnt);
490  addEvent(buff.data(), nwords_per_fee, cnt, ncpr, nhslb);
491  // printf("cnt %d bytes\n", cnt*total_words); fflush(stdout);
492  // sprintf( buff, "event %d dessa", cnt );
493 
494  // for(int i = 0 ; i < total_words ; i++){
495  // printf("%.8x ", buff[ i ]);
496  // if( i % 10 == 9 ) printf("\n");
497  // }
498 
499  int Ret = 0;
500  if ((Ret = write(connfd, buff.data(), total_words * sizeof(int))) <= 0) {
501  printf("[FATAL] Return value %d\n", Ret);
502  fflush(stdout);
503  exit(1);
504  }
505 
506  cnt++;
507 
508  if (cnt == start_cnt) init_time = getTimeSec();
509  if (cnt % 10000 == 1) {
510  if (cnt > start_cnt) {
511  double cur_time = getTimeSec();
512  printf("run %d evt %lld time %.1lf dataflow %.1lf MB/s rate %.2lf kHz : so far dataflow %.1lf MB/s rate %.2lf kHz size %d\n",
513  run_no,
514  cnt,
515  cur_time - init_time,
516  (cnt - prev_cnt)*total_words * sizeof(int) / 1000000. / (cur_time - prev_time),
517  (cnt - prev_cnt) / (cur_time - prev_time) / 1000.,
518  (cnt - start_cnt)*total_words * sizeof(int) / 1000000. / (cur_time - init_time),
519  (cnt - start_cnt) / (cur_time - init_time) / 1000., total_words);
520 
521  fflush(stdout);
522  prev_time = cur_time;
523  prev_cnt = cnt;
524  } else {
525  // printf("Eve %lld\n", cnt);fflush(stdout);
526  }
527  }
528  }
529  close(connfd);
530 }
int main(int argc, char **argv)
Run all tests.
Definition: test_main.cc:91