Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

bogus_beammon.c

Go to the documentation of this file.
00001 
00002 #include <stdio.h>
00003 /* #include <getopt.h> seems to be part of <unistd.h> */
00004 #include <unistd.h>
00005 /* stdlib.h:  malloc and atoi */
00006 #include <stdlib.h>
00007 /* string.h: strrchr */
00008 #include <string.h>
00009 
00010 #include "OnlineUtil/msgLogLib/msgLog.h"
00011 #include "OnlineUtil/rototalk.h"
00012 
00013 /* timeval, gettimeofday */
00014 #include <time.h>
00015 #include <sys/time.h>
00016 
00017 #include "OnlineUtil/rawBlockIds.h"
00018 #include "OnlineUtil/rdChecksum.h"
00019 #include "OnlineUtil/rotoMessages.h"
00020 
00021 /* forward declarations */
00022 int send_bogus_stuff(long* buffer, int bsize, int mxrec);
00023 int config_autosave(const char* config);
00024 int config_compress(const char* config);
00025 int config_basketsize(const char* config);
00026 long build_beammon_blockid(int major);
00027 
00028 /* (default) maximum buffer size for raw records (in bytes) */
00029 #define MAXBUFFER 8388608
00030 
00031 /*
00032  *=========================================================================
00033  * main(int argc, char **argv)
00034  * 
00035  * Purpose:
00036  *    Generate and send a series of fake DCS records to the Rotorooter
00037  *
00038  *   usage: bogus_dcs -i<hostname> -b<buffer size> 
00039  *           -w<whoami> -p<port #> 
00040  *           -c"autosave_configstring" 
00041  *           -C"compress_configstring" 
00042  *           -B"basketsize_configstring" 
00043  *
00044  *     -i: hostname where rotorooter is running
00045  *     -b: buffer size to use
00046  *     -c: autosave config    "streamName,nrec,nsec[;streamName,nrec,nsec]" 
00047  *     -C: compression config "streamName,level[;streamName,level]"
00048  *     -B: basketsize config "streamName,size[;streamName,size]"
00049  *            both -c,-C,-B use "*" as streamName to set all legal streams
00050  *     -w: DCP or DCS or BeamMon
00051  *     -p: port number rotorooter is listening on
00052  *     -v: how verbose to be
00053  *     -n: maximum number of records from each file
00054  *     -h: print this message
00055  *
00056  * Return Value:
00057  *    non-zero indicates there was an error
00058  *=========================================================================
00059  */
00060 int main(int argc, char **argv)
00061 {
00062 
00063    /* this is C ... all declarations must come first */
00064    const char* iphost = "localhost";
00065    const char* default_producer = "BeamMon";   /* default producer */
00066    const int   default_port     = 9013;        /* default BeamMon port */
00067    const char* producer = default_producer;
00068    const char* autosave_config = 0;
00069    const char* compress_config = 0;
00070    const char* basketsize_config = 0;
00071    int port = default_port;
00072    int whoami = MINOS_ROOTER_BEAMMON;
00073    int bsize = MAXBUFFER;
00074    long* buffer = 0;
00075    int nerr = 0;
00076    int mxrec = 1000;  /* no input file, so limit how much stuff to send */
00077    int nodelay_flag = 1;  /* on by default */
00078    int echoMsgLog = 0;
00079    int copt;
00080 
00081    /*
00082     * parse the options and filenames
00083     * -i and -p take args
00084     */
00085    while ((copt = getopt(argc, argv, "i:b:c:C:B:w:p:ev:n:D:h")) != EOF) {
00086       switch (copt) {
00087       case 'i':  /* internet host */
00088          iphost = optarg;
00089          break;
00090       case 'b':  /* buffer size */
00091          bsize = atoi(optarg);
00092          break;
00093       case 'c':  /* autosave config string */
00094          autosave_config = optarg;
00095          break;
00096       case 'C':  /* compression config string */
00097          compress_config = optarg;
00098          break;
00099       case 'B':  /* basketsize config string */
00100          basketsize_config = optarg;
00101          break;
00102       case 'w':  /* whoami:  DCP, DCS, other */
00103          producer = optarg;
00104          break;
00105       case 'p':  /* port # */
00106          port = atoi(optarg);
00107          break;
00108       case 'e':  /* msgLog messages to stdout as well */
00109          echoMsgLog = 1;
00110          break;
00111       case 'v':  /* verbosity */
00112          roto_verbose = atoi(optarg);
00113          break;
00114       case 'n':  /* maximum number of records */
00115          mxrec = atoi(optarg);
00116          break;
00117       case 'D':  /* set nodelay_flag? */
00118          nodelay_flag = atoi(optarg);
00119          break;
00120       case 'h':  /* help */
00121          printf(" usage: %s -i<hostname> -b<buffer size> -w<whoami> -p<port #> <filenames..>\n", argv[0]);
00122          printf("   -i: hostname where rotorooter is running\n");
00123          printf("   -b: buffer size to use\n");
00124          printf("   -w: DCP, DCS or BeamMon\n");
00125          printf("   -p: port number rotorooter is listening on\n");
00126          printf("   -v: how verbose to be\n");
00127          printf("   -c: autosave config \"streamName,nrec,nsec[;streamName,nrec,nsec]\"\n");
00128          printf("   -C: compression config \"streamName,level[;streamName,level]\"\n");
00129          printf("   -B: basketsize config \"streamName,size[;streamName,size]\"\n");
00130 
00131          printf("   -n: maximum number of records from each file\n");
00132 
00133          printf("   -h: print this message\n");
00134          exit(1);
00135       default:
00136          printf(" unrecognized option '%c' ignored\n",(char)optopt);
00137          break;
00138       }
00139    }
00140 
00141    msgLogInit(argv[0]);
00142    msgLogNodeIdSet(whoami);
00143    msgLogLocalEchoSet(echoMsgLog);
00144    logNotice("starting %s",argv[0]);
00145 
00146    /* allocate a buffer to use */
00147    buffer = (long*) malloc(bsize);
00148    if (!buffer) {
00149       printf("failed to allocate buffer of size %d\n",bsize);
00150       exit(1);
00151    }
00152    if (roto_verbose>1) printf("allocated buffer of size %d\n",bsize);
00153 
00154    /* open a connection to the Rotorooter */
00155    if (0 == strcmp(producer,default_producer) && 
00156        port == default_port) {
00157       /* standard connection */
00158       if (roto_verbose>1) 
00159          printf("connect via roto_open_BeamMon_connection\n");
00160       nerr += roto_open_BeamMon_connection(iphost);
00161    } else {
00162       /* non-standard connection requested (either producer or port) */
00163       if (0 == strcmp(producer,"DCP")) {
00164          whoami  = MINOS_ROOTER_DCP;
00165       }
00166       else if (0 == strcmp(producer,"DCS")) {
00167          whoami = MINOS_ROOTER_DCS;
00168       }
00169       else if (0 == strcmp(producer,"BeamMon")) {
00170          whoami = MINOS_ROOTER_BEAMMON;
00171       }
00172       else 
00173          whoami = MINOS_ROOTER_UNIDENTIFIED_CLIENT;
00174 
00175       if (roto_verbose>1) 
00176          printf("connect via roto_open_connection: port %d, whoami %s (0x%2.2x)\n",port,producer,whoami);
00177       nerr += roto_open_connection(iphost,port,whoami);
00178    }
00179    if (nerr) exit(nerr);
00180    
00181    nerr += roto_set_connection_nodelay(nodelay_flag);
00182 
00183    if (autosave_config) nerr += config_autosave(autosave_config);
00184    if (compress_config) nerr += config_compress(compress_config);
00185    if (basketsize_config) nerr += config_basketsize(basketsize_config);
00186 
00187    nerr += send_bogus_stuff(buffer,bsize,mxrec);
00188 
00189    /* close the connection */
00190    nerr += roto_close_connection();
00191 
00192    /* set my buffer free */
00193    free(buffer);
00194 
00195    logNotice("stopping %s",argv[0]);
00196    msgLogCleanup();
00197 
00198    exit(nerr);
00199 }
00200 
00201 /*
00202  *=========================================================================
00203  * send_bogus_stuff(long* buffer, int bsize, int mxrec) 
00204  * 
00205  * Purpose:
00206  *    Send a series of bogus BeamMon records to the rotorooter
00207  *
00208  * Arguments:
00209  *    buffer:  ptr to pre-allocated buffer
00210  *    bsize:   buffer size
00211  *    mxrec:   maximum number of records to send (0=all)
00212  *
00213  * Return Value:
00214  *    non-zero indicates there was an error
00215  *=========================================================================
00216  */
00217 int send_bogus_stuff(long* buffer, int bsize, int mxrec) 
00218 {
00219 
00220    int   nRecords=0;
00221    int   nbytes;
00222    int   nextra, j;
00223    const float nextra_max = 100.0;
00224    int   blktype;
00225    unsigned int spillcnt = 0;
00226 
00227    int nerr = 0;
00228 
00229    struct timeval now;
00230    gettimeofday(&now,0);
00231 
00232    nerr += roto_open_beammonfile(now.tv_sec,now.tv_usec*1000);
00233    if (nerr) {
00234       printf("Rotorooter failed to open output file\n");
00235       return 1;
00236    }
00237 
00238    while (1) {
00239       if (mxrec>0 && nRecords==mxrec) break;
00240       nRecords++;
00241       /* fill a BeamMon record */
00242       /*
00243        * 0 BeamMonHeaderBlock size
00244        * 1                checksum
00245        * 2                blockid
00246        * 3                sec
00247        * 4                ns
00248        * 5                spillcnt
00249        * 6 {In|OutOf}SpillBeamMonBlock size
00250        * 7                         checksum
00251        * 8                         blockid
00252        * 9..                       <stuff>
00253        */
00254       /* see Linux "man -s 3 rand" on why whe do this */
00255       nextra = 1+(int) (nextra_max*rand()/(RAND_MAX+1.0));
00256       nbytes = (9+nextra)*sizeof(int);
00257       if (nbytes>bsize) {
00258         nbytes = bsize;
00259         nextra = nbytes/sizeof(int) - 9;
00260       }
00261       blktype = kMdBlockBeamMonPayload;
00262 
00263       buffer[0] = 6; /* BeamMonHeaderBlock size */
00264       /* skip checksum */
00265       buffer[2] = build_beammon_blockid(kMdBlockBeamMonHeader);
00266       gettimeofday(&now,0);
00267       buffer[3] = now.tv_sec;
00268       buffer[4] = now.tv_usec*1000;
00269       buffer[5] = ++spillcnt;
00270       /* now fill in checksum */
00271       buffer[1] = rdxsum_calc(buffer+0,1);
00272 
00273       buffer[6] = 3 + nextra; /* {In|OutOf}SpillBeamMonBlock size */
00274       /* skip checksum */
00275       buffer[8] = build_beammon_blockid(blktype);
00276       /* fill in some arbitrary stuff */
00277       for (j=0; j<nextra; ++j) buffer[j+9] = rand();
00278       /* now fill in checksum */
00279       buffer[7] = rdxsum_calc(buffer+6,1);
00280                                  
00281       /* send the record */
00282       nerr += roto_send_record(buffer,nbytes);
00283    }
00284 
00285    nerr += roto_close_beammonfile();
00286    return nerr;
00287 }
00288 
00289 /*
00290  *=========================================================================
00291  * config_autosave(const char* config)
00292  * 
00293  * Purpose:
00294  *    Send autosave config to the rotorooter, parsed from string
00295  *
00296  * Arguments:
00297  *    config:  configuration string of form:
00298  *             "streamName,nrec,nsec[;streamName,nrec,nsec]"
00299  *             use "*" as streamName to set all legal streams
00300  * 
00301  * Return Value:
00302  *    non-zero indicates there was an error
00303  *=========================================================================
00304  */
00305 int config_autosave(const char* config)
00306 {
00307    int nerr = 0;
00308    int len = strlen(config);
00309    char *wcopy = (char*)malloc(len+1);  /* a writable copy of config string */
00310    char stream[1024];
00311    const char *p1;
00312    char *p2;
00313    char achar;
00314    int nrec,nsec, nitems;
00315 
00316    /* make a copy, replacing all the commas with blanks*/
00317    p1 = config; p2 = wcopy;
00318    while (p2 < wcopy+len) {
00319       achar = *p1;
00320       if (achar != ',') *p2 = achar;
00321       else              *p2 = ' ';
00322       p1++; p2++;
00323    }
00324 
00325    p2 = wcopy;
00326    while (p2  < wcopy+len) {
00327       nitems = sscanf(p2,"%s %d %d",stream,&nrec,&nsec);
00328       if (nitems != 3) {
00329          logInfo("config_autosave: only %d items from \"%s\"\n",nitems,p2);
00330          nerr += rototalk_err_badconfig;
00331       }
00332       else 
00333          nerr += roto_send_autosave_config(stream,nrec,nsec);
00334 
00335       p2 = strchr(p2,';'); /* move to the semicolon         */
00336       if (!p2) break;      /* in case of no final semicolon */
00337       p2++;                /* start just beyond semicolon   */
00338    }
00339 
00340 
00341    free(wcopy);  /* return the allocated space */
00342    wcopy = 0;
00343 
00344    return nerr;
00345 }
00346 
00347 /*
00348  *=========================================================================
00349  * config_compress(const char* config)
00350  * 
00351  * Purpose:
00352  *    Send compression config to the rotorooter, parsed from string
00353  *
00354  * Arguments:
00355  *    config:  configuration string of form:
00356  *             "streamName,level[;streamName,level]"
00357  *             use "*" as streamName to set all legal streams
00358  * 
00359  * Return Value:
00360  *    non-zero indicates there was an error
00361  *=========================================================================
00362  */
00363 int config_compress(const char* config)
00364 {
00365    int nerr = 0;
00366    int len = strlen(config);
00367    char *wcopy = (char*)malloc(len+1);  /* a writable copy of config string */
00368    char stream[1024];
00369    const char *p1;
00370    char *p2;
00371    char achar;
00372    int level, nitems;
00373 
00374    /* make a copy, replacing all the commas with blanks*/
00375    p1 = config; p2 = wcopy;
00376    while (p2 < wcopy+len) {
00377       achar = *p1;
00378       if (achar != ',') *p2 = achar;
00379       else              *p2 = ' ';
00380       p1++; p2++;
00381    }
00382 
00383    p2 = wcopy;
00384    while (p2  < wcopy+len) {
00385       nitems = sscanf(p2,"%s %d",stream,&level);
00386       if (nitems != 2) {
00387          logInfo("config_compress: only %d items from \"%s\"\n",nitems,p2);
00388          nerr += rototalk_err_badconfig;
00389       }
00390       else 
00391          nerr += roto_send_compress_config(stream,level);
00392 
00393       p2 = strchr(p2,';'); /* move to the semicolon         */
00394       if (!p2) break;      /* in case of no final semicolon */
00395       p2++;                /* start just beyond semicolon   */
00396    }
00397 
00398 
00399    free(wcopy);  /* return the allocated space */
00400    wcopy = 0;
00401 
00402    return nerr;
00403 }
00404 
00405 /*
00406  *=========================================================================
00407  * config_basketsize(const char* config)
00408  * 
00409  * Purpose:
00410  *    Send basketsize config to the rotorooter, parsed from string
00411  *
00412  * Arguments:
00413  *    config:  configuration string of form:
00414  *             "streamName,bsize[;streamName,bsize]"
00415  *             use "*" as streamName to set all legal streams
00416  * 
00417  * Return Value:
00418  *    non-zero indicates there was an error
00419  *=========================================================================
00420  */
00421 int config_basketsize(const char* config)
00422 {
00423    int nerr = 0;
00424    int len = strlen(config);
00425    char *wcopy = (char*)malloc(len+1);  /* a writable copy of config string */
00426    char stream[1024];
00427    const char *p1;
00428    char *p2;
00429    char achar;
00430    int bsize, nitems;
00431 
00432    /* make a copy, replacing all the commas with blanks*/
00433    p1 = config; p2 = wcopy;
00434    while (p2 < wcopy+len) {
00435       achar = *p1;
00436       if (achar != ',') *p2 = achar;
00437       else              *p2 = ' ';
00438       p1++; p2++;
00439    }
00440 
00441    p2 = wcopy;
00442    while (p2  < wcopy+len) {
00443       nitems = sscanf(p2,"%s %d",stream,&bsize);
00444       if (nitems != 2) {
00445          logInfo("config_basketsize: only %d items from \"%s\"\n",nitems,p2);
00446          nerr += rototalk_err_badconfig;
00447       }
00448       else 
00449          nerr += roto_send_basketsize_config(stream,bsize);
00450 
00451       p2 = strchr(p2,';'); /* move to the semicolon         */
00452       if (!p2) break;      /* in case of no final semicolon */
00453       p2++;                /* start just beyond semicolon   */
00454    }
00455 
00456 
00457    free(wcopy);  /* return the allocated space */
00458    wcopy = 0;
00459 
00460    return nerr;
00461 }
00462 
00463 /*
00464  *=========================================================================
00465  * long build_beammon_blockid(int major)
00466  * 
00467  * Purpose:
00468  *    Generate a block id  (force DCS, bogus simflag)
00469  *
00470  * Arguments:
00471  *    major    : major block id
00472  * 
00473  * Return Value:
00474  *    non-zero indicates there was an error
00475  *=========================================================================
00476  */
00477 long build_beammon_blockid(int major)
00478 {
00479    const long  shiftRawBlkIdMinor    =  0;
00480    const long  shiftRawBlkIdMajor    =  8;
00481    const long  shiftRawBlkIdDetector = 25;
00482    const long  shiftRawBlkIdCSimFlag = 28;
00483    
00484    const long  maskRawBlkIdMinor     = 0x000000ff;
00485    const long  maskRawBlkIdMajor     = 0x00ffff00;
00486    const long  maskRawBlkIdIsDCS     = 0x01000000;
00487    const long  maskRawBlkIdDetector  = 0x0e000000;
00488    const long  maskRawBlkIdCSimFlag  = 0x30000000;
00489 
00490    int cmptSimFlag = 1;  /* compact simflag for DaqFakeData */
00491    int isDCS = 1;
00492    int minor = 0;
00493    int detector = 0;
00494 
00495    return
00496       ((cmptSimFlag << shiftRawBlkIdCSimFlag) & maskRawBlkIdCSimFlag) |
00497       ((   detector << shiftRawBlkIdDetector) & maskRawBlkIdDetector) |
00498       ((isDCS) ? maskRawBlkIdIsDCS : 0)                               |
00499       ((         major << shiftRawBlkIdMajor) & maskRawBlkIdMajor)    |
00500       ((         minor << shiftRawBlkIdMinor) & maskRawBlkIdMinor);
00501 
00502 }

Generated on Mon Feb 15 11:06:26 2010 for loon by  doxygen 1.3.9.1