// // g++ epics2cdaq.cc -o epics2cdaq.exe // ./epics2cdaq.exe -host=gluon43 // #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include // #define PACKSIZE 400111 #define DEBUG 2 #define T_WAIT 1 static char HOST[128]; static int PORT=20249; static int TCP_FLAG; static int current_sd=0; static int HOLD_TIME=0; //--- assume only one sender (DC) !!! //------------------------------------------------------------------------------------------------------- int tcp_event_host(char *host, int port) { strncpy(HOST,host,128); PORT=port; printf("==>> TCPclient:: set HOST=%s PORT=%d \n",HOST,PORT); } //--------------------------------------------------------------------------------------------------------------- int tcp_event_snd( unsigned int *DATA, int lenDATA,int n,int k, unsigned int evtHDR, unsigned int TriggerID ) { static char hostname[100]; static int sd; static struct sockaddr_in pin; struct hostent *hp; static int TCP_FLAG,HEADER[10]; int nleft,nsent; static unsigned int time0,time1; char* snd; // 0=initial -1 -no connection -2 error send if (PORT==0) { //-- set HOST and PORT to default: localhost:20249 strncpy(HOST,"localhost",128); PORT=20249; printf("==> TCPclient:: set DEFAULT!! HOST=%s PORT=%d \n",HOST,PORT); } if(TCP_FLAG==0) { TCP_FLAG=-2; time((time_t*)&time0); strcpy(hostname,HOST); printf("TCPclient:: go find out about the desired host machine \n"); if ((hp = gethostbyname(hostname)) == 0) { perror("gethostbyname"); return -1; } printf( "IP=%u.%u.%u.%u \n", (unsigned char) hp->h_addr_list[0][0], (unsigned char) hp->h_addr_list[0][1], (unsigned char) hp->h_addr_list[0][2], (unsigned char) hp->h_addr_list[0][3]); //-------- fill in the socket structure with host information memset(&pin, 0, sizeof(pin)); pin.sin_family = AF_INET; pin.sin_addr.s_addr = ((struct in_addr *)(hp->h_addr))->s_addr; pin.sin_port = htons(PORT); //-------- grab an Internet domain socket if ((sd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { perror("socket"); return -1; } printf("TCPclient:: try to connect to %s port=%d\n",hostname,PORT); //------- connect to PORT on HOST if (connect(sd,(struct sockaddr *) &pin, sizeof(pin)) == -1) { perror("connect"); return -1; } printf("TCPclient:: CONNECTED to %s port=%d local_sock=%d port=%d\n",hostname,PORT,sd,ntohs(pin.sin_port)); TCP_FLAG=1; //--- server OK, send DATA } else if (TCP_FLAG==-1) { //--- no server (error connect) time((time_t*)&time1); //---- timer for retry printf("TCPclient:: t1=%d t0=%d t1-t0=%d \n",time1,time0,time1-time0); if ((time1-time0) > T_WAIT ) { time0=time1; printf("TCPclient:: %d RE-try to connect to %s\n",time1-time0,hostname); TCP_FLAG=0; }; return -1; } else if (TCP_FLAG==-2) { //--- server disappeared (error send) printf("TCPclient:: close socket... %s\n",hostname); close(sd); time((time_t*)&time0); TCP_FLAG=-1; return -1; }; //-------------------------------------------------- //------------ ENDIF TCP_FLAG ------------------- //-------------------------------------------------- HEADER[0]=0x5; //--- buffered for evb HEADER[1]=0xAABBCCDD; HEADER[2]=lenDATA; HEADER[3]=evtHDR; HEADER[4]=TriggerID; HEADER[5]=n; HEADER[6]=k; HEADER[7]=k; #ifdef DEBUG printf("send HEADER size=%d\n",sizeof(HEADER)); #endif if (send(sd, (char*) HEADER, sizeof(HEADER), 0) == -1) { perror("send"); TCP_FLAG=-2; return -1; } #ifdef DEBUG printf("send DATA lenDATA=%d bytes (%d words) nmod=%d mod=%d trigger=%d\n",lenDATA*4,lenDATA,n,k, TriggerID); #endif nleft=lenDATA*4; snd=(char*)DATA; while(nleft>0){ if(DEBUG>3) printf("try to send = %d of %d\n",PACKSIZE,nleft); if (nleft [-cmd=] [-host=HOST[:PORT]] [-d[elay]=usec] -p[rescale=N]\n\n",argv[0]); //sleep(1); exit(1); } else { for (int ii=1;ii ",ii,argv[ii]); //------------------------------------------------------------------- if(STREQ(argv[ii],"-host") ) { if ((substr1=strstr(argv[ii],"="))) { printf("found /=/ |%s|\n",substr1); if ((substr2=strstr(argv[ii],":"))) { int Lhost=(substr2-substr1)-1; printf("found /:/ |%s|, Lhost=%d\n",substr2,Lhost); strncpy(DATA_HOST,&substr1[1],Lhost); DATA_HOST[Lhost]=0; DATA_PORT=atoi(&substr2[1]); } else { strncpy(DATA_HOST,&substr1[1],LHOST); } } } //------------------------------------------------------------------- if(STREQ(argv[ii],"-d")) { //-- -delay if ((substr1=strstr(argv[ii],"="))) { printf("found /=/ |%s|\n",substr1); udelay=atoi(&substr1[1]); } } //------------------------------------------------------------------- } //-- end for(ii= } if (REQUEST==0) REQUEST=0x1002; //--- default req one event // printf(" CMD_HOST=%s PORT=%d\n",CMD_HOST,CMD_PORT); printf("DATA_HOST=%s PORT=%d\n",DATA_HOST,DATA_PORT); printf("REQUEST=%#X \n",REQUEST); printf("CMD=%d (0->recv, 1-> send) \n",CMD); printf("Delay=%d \n",udelay); printf("N_mod=%d \n",nmod); printf("Prescale=%d \n",prescale); sleep(3); //----------------------------------------------------------------------- signal(SIGPIPE,fpipe); signal(SIGINT,ctrl_c); const unsigned int BORE_TRIGGERID = 0x55555555; const unsigned int EORE_TRIGGERID = 0xAAAAAAAA; const unsigned int EPICS_TRIGGERID= 0xAAAA5555; int evt_type, temperature; int dev_type, ZSbit,SuccFrames; if (CMD==1) { //-------------------- S E N D --------------------------- tcp_event_host(DATA_HOST, DATA_PORT); unsigned int EVT_Type_BOR=(0x0&0xFF)<<16; //-- BOR=0x0 unsigned int EVT_Type_EOR=(0x1&0xFF)<<16; //-- EOR=0x1 unsigned int EVT_Type_DATA=(0x2&0xFF)<<16; //-- DATA=0x2 unsigned int EVT_Type_EPICS=(0x3&0xFF)<<16; //-- EPICS=0x3 while(!sig_int) { //--- EPICS data -- itrg++; LENEVENT=8195; BUFFER[0]=1&0xff ; //-- number of ROCs=1 (max 255 !) BUFFER[0] |= EVT_Type_EPICS; int RocID=0xFF; // epics ID unsigned int MODID=(RocID&0xFF)<<24; //-- ModID 8-bit IP based BUFFER[0] |= MODID; BUFFER[1]=EPICS_TRIGGERID; BUFFER[2]=LENEVENT; //-- hdr=(i & 0xF) << 24; unsigned int evtTrigID=BUFFER[1]; int evtModID=(BUFFER[0]>>24)&0xf; int evtSize=BUFFER[0]&0xfffff; printf("==> SEND:: Trg=%d(%d,%d) Mod=%d(%d) siz=%d(%d), rate=%.1f data=%.3f GB/s\n" ,evtTrigID,itrg,BUFFER[1],evtModID,i,evtSize,LENEVENT,rate,LENEVENT*4*rate*nmod/1073741824.); rc=tcp_event_snd(BUFFER,LENEVENT,nmod,i,hdr,itrg); if (rc<0) { printf(" ERROR send \n"); sleep(1); } if (udelay) usleep (udelay); // } //-- end while(!sig_int) } return 0; } //__________________________________________________________________________________ // The following copied from epics2et.cc //-------------------- // BuildEPICSEvent //-------------------- uint32_t BuildEPICSEvent(uint32_t *buff, map &epics_vals) { // Store the EPICS event in EVIO as a bank of SEGMENTs // The first segment is a 32-bit unsigned int for the current // time. This is followed by additional SEGMENTs that are // 8-bit unsigned integer types, one for each variable being // written. All variables are written as strings in the form: // // varname=value // // where "varname" is the EPICS variable name and "value" its // value in string form. If there are multiple elements for // the PV, then value will be a comma separated list. The // contents of "value" are set in GetEPICSvalue() while // the "varname=value" string is formed here. buff[0] = 0; // initialize to zero in case we exit early // If no values to write then return now if(epics_vals.size() == 0) return 0; // Outermost EVIO header is a bank of segments. uint32_t *iptr = &buff[1]; // skip length word // Overall bank header indicating it contains SEGMENTs *iptr++ = (0x60<<16) + (0xD<<8) + (0x1<<0); // Time word (unsigned 32bit SEGMENT) *iptr++ = (0x61<<24) + (0x1<<16) + (1<<0); *iptr++ = (uint32_t)atol(epics_vals["timestamp"].c_str()); // Loop over PVs, writing each as a SEGMENT to the buffer map::iterator iter=epics_vals.begin(); for(; iter!=epics_vals.end(); iter++){ const string &name = iter->first; const string &val = iter->second; string str = name + "=" + val; uint32_t Nbytes = str.size()+1; // +1 is for terminating 0 uint32_t Nwords = (Nbytes+3)/4; // bytes needed for padding uint32_t Npad = (Nwords*4) - Nbytes; *iptr++ = (0x62<<24) + (Npad<<22) + (0x7<<16) + (Nwords<<0); // 8bit unsigned char segment unsigned char *ichar = (unsigned char*)iptr; for(unsigned int j=0; j &epics_vals) { // This routine will loop over the list of EPICs PVs and // try to get each one. Values that it successfully retrieves // will be copied into the caller-supplied "epics_vals" map. // In addition, the current time to associate with these // readings is copied into the map with the key "timestamp". // Get current time in seconds since 1970 uint32_t now = time(NULL); // Loop over the variable list and see if anyone is due to be written out for(int i=0;i EPICS_CHANNELS[i].last_read+EPICS_CHANNELS[i].period ){ string val = GetEPICSvalue(EPICS_CHANNELS[i]); if(val.length()>0){ epics_vals[EPICS_CHANNELS[i].name] = val; EPICS_CHANNELS[i].last_read = now; } } } // Don't add timestamp if no values! if(epics_vals.empty()) return 0; // Add timestamp char tstr[256]; sprintf(tstr, "%d", now); epics_vals["timestamp"] = tstr; // Return number of values return epics_vals.size(); } //-------------------- // GetEPICSvalue //-------------------- string GetEPICSvalue(epics_channel_t &ch) { // Alloocate array to hold all values uint32_t Nelem = ch.num_elements; float *fvals = new float[Nelem]; stringstream ss; // holds values in string form #ifdef HAVE_EZCA // Get the values int ret = ezcaGet((char*)(ch.name.c_str()), ezcaFloat, Nelem, fvals); // Form string of value(s) obtained) if(ret == EZCA_OK){ for(uint32_t i=0; i0) ss << ","; ss << fvals[i]; } }else{ cerr << "Error retrieving variable: " << ch.name << " (code=" << hex << ret << dec << ")" << endl; } #endif // HAVE_EZCA delete[] fvals; return ss.str(); } //__________________________________________________________________________________