Eiger::Eiger (const char *hostname) : mSockFd(0), mSockMutex(), mSockClosed(true) { strncpy(mHostname, hostname, sizeof(mHostname)); memset(&mAddress, 0, sizeof(mAddress)); if(hostToIPAddr(mHostname, &mAddress.sin_addr)) throw std::runtime_error("invalid hostname"); mAddress.sin_family = AF_INET; mAddress.sin_port = htons(HTTP_PORT); }
/* * rational replacement for inet_addr() * which allows the limited broadcast address * 255.255.255.255, allows the user * to specify a port number, and allows also a * named host to be specified. * * Sets the port number to "defaultPort" only if * "pAddrString" does not contain an address of the form * "n.n.n.n:p" */ epicsShareFunc int epicsShareAPI aToIPAddr(const char *pAddrString, unsigned short defaultPort, struct sockaddr_in *pIP) { int status; char hostName[512]; /* !! change n elements here requires change in format below !! */ char *endp; unsigned int port; unsigned long numaddr; struct in_addr ina; /* * Scan for a port number */ status = sscanf( pAddrString, " %511[^:]:%u", hostName, &port ); if ( status == 0 ) { return -1; } if ( status == 1 ) { port = defaultPort; } else if (status == 2 && port > 65535) { return -1; } /* * Look for a valid host name or dotted quad */ status = hostToIPAddr( hostName, &ina ); if ( status == 0 ) { return initIPAddr( ina, port, pIP ); } /* * Try the IP address as a decimal integer */ numaddr = strtoul( hostName, &endp, 10 ); if (*endp) return -1; ina.s_addr = htonl( numaddr ); return initIPAddr( ina, port, pIP ); }
/* * Create a link */ static asynStatus connectIt(void *drvPvt, asynUser *pasynUser) { ttyController_t *tty = (ttyController_t *)drvPvt; SOCKET fd; int i; /* * Sanity check */ assert(tty); asynPrint(pasynUser, ASYN_TRACE_FLOW, "Open connection to %s reason:%d fd:%d\n", tty->IPDeviceName, pasynUser->reason, tty->fd); if (tty->fd != INVALID_SOCKET) { epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize, "%s: Link already open!", tty->IPDeviceName); return asynError; } else if(tty->flags & FLAG_SHUTDOWN) { epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize, "%s: Link shutdown!", tty->IPDeviceName); return asynError; } /* If pasynUser->reason > 0) then use this as the file descriptor */ if (pasynUser->reason > 0) { fd = pasynUser->reason; } else { /* * Create the socket */ if ((fd = epicsSocketCreate(tty->farAddr.oa.sa.sa_family, tty->socketType, 0)) < 0) { epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize, "Can't create socket: %s", strerror(SOCKERRNO)); return asynError; } /* * Enable broadcasts if so requested */ i = 1; if ((tty->flags & FLAG_BROADCAST) && (setsockopt(fd, SOL_SOCKET, SO_BROADCAST, (void *)&i, sizeof i) < 0)) { epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize, "Can't set %s socket BROADCAST option: %s", tty->IPDeviceName, strerror(SOCKERRNO)); epicsSocketDestroy(fd); return asynError; } /* * Convert host name/number to IP address. * We delay doing this until now in case a device * has just appeared in a DNS database. */ if (tty->flags & FLAG_NEED_LOOKUP) { if(hostToIPAddr(tty->IPHostName, &tty->farAddr.oa.ia.sin_addr) < 0) { epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize, "Unknown host \"%s\"", tty->IPHostName); epicsSocketDestroy(fd); return asynError; } tty->flags &= ~FLAG_NEED_LOOKUP; tty->flags |= FLAG_DONE_LOOKUP; } /* * Bind to the local IP address if it was specified. * This is a very unusual configuration */ if (tty->localAddrSize > 0) { if (bind(fd, &tty->localAddr.sa, tty->localAddrSize)) { epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize, "unable to bind to local port: %s", strerror(SOCKERRNO)); epicsSocketDestroy(fd); return asynError; } } /* * Connect to the remote host * If the connect fails, arrange for another DNS lookup in case the * problem is just that the device has DHCP'd itself an new number. */ if (tty->socketType != SOCK_DGRAM) { if (connect(fd, &tty->farAddr.oa.sa, (int)tty->farAddrSize) < 0) { epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize, "Can't connect to %s: %s", tty->IPDeviceName, strerror(SOCKERRNO)); epicsSocketDestroy(fd); if (tty->flags & FLAG_DONE_LOOKUP) tty->flags |= FLAG_NEED_LOOKUP; return asynError; } } } i = 1; if ((tty->socketType == SOCK_STREAM) && (tty->farAddr.oa.sa.sa_family == AF_INET) && (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (void *)&i, sizeof i) < 0)) { epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize, "Can't set %s socket NODELAY option: %s", tty->IPDeviceName, strerror(SOCKERRNO)); epicsSocketDestroy(fd); return asynError; } #ifdef USE_POLL if (setNonBlock(fd, 1) < 0) { epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize, "Can't set %s O_NONBLOCK option: %s", tty->IPDeviceName, strerror(SOCKERRNO)); epicsSocketDestroy(fd); return asynError; } #endif asynPrint(pasynUser, ASYN_TRACE_FLOW, "Opened connection to %s\n", tty->IPDeviceName); tty->fd = fd; return asynSuccess; }
int main(int argc, char**argv) { struct sockaddr_in si_me; struct sockaddr_in moderator_udp_sockaddr; unsigned short packet_tag; unsigned int i,j,temp_NPACK; SOCKET s, moderator_udp_sock_fd; int this_frame_has_aligment_errors=0; char temp_char; unsigned int packet_id, local_packet_id; long packet_id_gap; int received_data_subsets=0; moderation_type moderation=NOUDPMOD; clock_t timer_a=0,timer_b; double time_interval; char moderator_string[MAX_STRLEN]; id_mode packet_id_mode; ptr_list = epicsMessageQueueCreate(MAX_PENDING_BUFFERS, sizeof(unsigned char *)); if (ptr_list == 0) { printf("epicsMessageQueueCreate failed\n"); return -1; } if (osiSockAttach() == 0) { printf("osiSockAttach failed\n"); return -1; } if(argc==4){ if (strcmp(argv[3],"UDPMOD")==0) moderation=UDPMOD; else moderation=NOUDPMOD; verbose=atoi(argv[2]); if (strcmp(argv[1],"FRAG_ID")==0) packet_id_mode=FRAG_ID; else packet_id_mode=NOFRAG_ID; } if(argc==3){ verbose=atoi(argv[2]); if (strcmp(argv[1],"FRAG_ID")==0) packet_id_mode=FRAG_ID; else packet_id_mode=NOFRAG_ID; } else if(argc==2){ verbose=0; if (strcmp(argv[1],"FRAG_ID")==0) packet_id_mode=FRAG_ID; else packet_id_mode=NOFRAG_ID; } else{ verbose=0; packet_id_mode=FRAG_ID; moderation=NOUDPMOD; } buf=(unsigned char*)databuffer_allocation(MAX_PACK_LEN*DEFAULT_NPACK); if ((s=epicsSocketCreate(AF_INET, SOCK_DGRAM, IPPROTO_UDP))==-1) { printf("\r\nError creating socket error =%s", strerror(errno)); scanf("%c%*c",&temp_char); return 1; } memset((char *) &si_me, 0, sizeof(si_me)); si_me.sin_family = AF_INET; si_me.sin_port = htons(PORTA); si_me.sin_addr.s_addr = htonl(INADDR_ANY); if (bind(s, (struct sockaddr *) &si_me, sizeof(si_me))==-1) { printf("\r\nError in binding data receiver socket"); //wait_akey(); return 1; } if ((moderator_udp_sock_fd=epicsSocketCreate(AF_INET, SOCK_DGRAM, IPPROTO_UDP))==-1) { printf("\r\nError creating moderator socket error =%s", strerror(errno)); scanf("%c%*c",&temp_char); return 1; } memset((char *) &moderator_udp_sockaddr, 0, sizeof(moderator_udp_sockaddr)); moderator_udp_sockaddr.sin_family = AF_INET; moderator_udp_sockaddr.sin_port = htons(MOD_UDP_REMOTE_PORT); // The following is not support on Linux. Is it needed? if (hostToIPAddr("192.168.0.255", &moderator_udp_sockaddr.sin_addr) < 0) printf("PROC:hostToIPAddr failed\n"); //moderator_udp_sockaddr.sin_addr.S_un.S_un_b.s_b1=192; //l'indirizzo IP!!! //moderator_udp_sockaddr.sin_addr.S_un.S_un_b.s_b2=168; //moderator_udp_sockaddr.sin_addr.S_un.S_un_b.s_b3=0; //moderator_udp_sockaddr.sin_addr.S_un.S_un_b.s_b4=255; int buffsize; osiSocklen_t czm = sizeof( int); int received_bytes; buffsize = MAXBUF; if (setsockopt(s, SOL_SOCKET, SO_RCVBUF, (char*)&buffsize, czm) != -1) { if(verbose>=2)printf("\r\nTrying to set Receive Buffer = %d", buffsize); } if (getsockopt(s, SOL_SOCKET, SO_RCVBUF, (char*)&buffsize, &czm) != -1) { if(verbose>=2)printf("\r\nReceive buffer is now = %d ", buffsize); if (buffsize == MAXBUF) { if(verbose>=2)printf("OK"); } else { if(verbose>=2)printf("ERROR Buffer Size too big!"); } } epicsThreadCreate("key_proc", epicsThreadPriorityMedium, epicsThreadGetStackSize(epicsThreadStackMedium), (EPICSTHREADFUNC)key_proc, (void*)&i); epicsThreadCreate("module_data_parser_thread", epicsThreadPriorityMedium, epicsThreadGetStackSize(epicsThreadStackMedium), (EPICSTHREADFUNC)module_data_parser_thread, NULL); while(looping){ // sem_wait(&(ptr_list.put_sem)); this_frame_has_aligment_errors=0; temp_NPACK=DEFAULT_NPACK; i=0; if(packet_id_mode==FRAG_ID){ while(i<temp_NPACK ){ j=0; while(j<DAQ_PACK_FRAGM){ received_bytes=recvfrom(s,(char*) buf+(i*MAX_PACK_LEN), MAX_PACK_LEN,0, NULL, 0); if (received_bytes== -1) printf("\rError receiveing datagram"); else if(received_bytes==MAX_PACK_LEN){ if(i==0) timer_a=clock(); received_packets++; packet_tag=*buf; if(packet_tag & AUTOCAL_DATA) temp_NPACK=AUTOCAL_NPACK; else temp_NPACK=DEFAULT_NPACK; /********************************************************************/; packet_id=buf[MAX_PACK_LEN*(i)+PACKET_ID_OFFSET]<<8; packet_id+=buf[MAX_PACK_LEN*(i)+1+PACKET_ID_OFFSET]; packet_id=packet_id%DAQ_PACK_FRAGM; packet_id_gap=(packet_id-j); if(packet_id_gap!=0){ if(id_error_packets<10) printf("ID: %d j= %d\n",packet_id,j); id_error_packets++; this_frame_has_aligment_errors=1; } if(packet_id_gap>=0){ j+=(packet_id_gap+1); i+=(packet_id_gap+1); } else{ j=DAQ_PACK_FRAGM; i+=DAQ_PACK_FRAGM; } } } if(moderation==UDPMOD){ sprintf(moderator_string,"DATASUBSET_RECEIVED %d %d\n",received_data_subsets,temp_NPACK/DAQ_PACK_FRAGM); received_data_subsets++; if (sendto(moderator_udp_sock_fd, moderator_string, strlen(moderator_string), 0, (struct sockaddr*)&moderator_udp_sockaddr, (osiSocklen_t)sizeof(moderator_udp_sockaddr))==-1) printf("\r\n!!Error sending moderating datagram!!"); } } } else{ while(i<temp_NPACK ){ received_bytes=recvfrom(s,(char*) buf+(i*MAX_PACK_LEN), MAX_PACK_LEN,0, NULL, 0); if (received_bytes== -1) printf("\rError receiveing datagram"); else if(received_bytes==MAX_PACK_LEN){ if(i==0) timer_a=clock(); //i++;j++; received_packets++; packet_tag=*buf; if(packet_tag & AUTOCAL_DATA) temp_NPACK=AUTOCAL_NPACK; else temp_NPACK=DEFAULT_NPACK; packet_id=buf[MAX_PACK_LEN*(i)+PACKET_ID_OFFSET]<<8; packet_id+=buf[MAX_PACK_LEN*(i)+1+PACKET_ID_OFFSET]; packet_id_gap=(packet_id-i);// if(packet_id_gap!=0){ id_error_packets++; this_frame_has_aligment_errors=1; } if(packet_id_gap>=0){ i+=(packet_id_gap+1); } else{ i=temp_NPACK; } if((i%DAQ_PACK_FRAGM)==0 && i!=0 && moderation==UDPMOD){ sprintf(moderator_string,"DATASUBSET_RECEIVED %d %d\n",received_data_subsets,temp_NPACK/DAQ_PACK_FRAGM); received_data_subsets++; if (sendto(moderator_udp_sock_fd, moderator_string, strlen(moderator_string), 0, (struct sockaddr*)&moderator_udp_sockaddr, sizeof(moderator_udp_sockaddr))==-1) printf("\r\n!!Error sending moderating datagram!!"); } } } } received_data_subsets=0; if(verbose>=1){ timer_b=clock(); time_interval=(double)(timer_b-timer_a)/CLOCKS_PER_SEC; printf("MAIN:%d packets(%d bytes each) have been received in %.3f s ",i,MAX_PACK_LEN,time_interval); printf("(%.3f Mbps)\n",(i*MAX_PACK_LEN*8)/(time_interval*1024*1024)); } i=0; local_packet_id=0; process_buf=(unsigned char*)databuffer_allocation((MAX_PACK_LEN-PACKET_EXTRA_BYTES+PACKET_TAG_BYTES)*DEFAULT_NPACK); if((buf==NULL)||(process_buf==NULL)){ printf("error allocating buffers\n"); exit(0); } else if(verbose>=1) printf("MAIN:New Processing Buffer Allocated\n"); while((i<temp_NPACK)) { memcpy(process_buf+PACKET_TAG_BYTES+(PACKET_SENSOR_DATA_BYTES*local_packet_id), buf+PACKET_SENSOR_DATA_OFFSET+(MAX_PACK_LEN*i), PACKET_SENSOR_DATA_BYTES); for(j=0;j<PACKET_TAG_BYTES;j++) process_buf[PACKET_TAG_OFFSET+j]=buf[j];//copio il PACKET_TAG del buffer per processing if(this_frame_has_aligment_errors) process_buf[PACKET_TAG_OFFSET]|=FRAME_HAS_ALIGN_ERRORS; else process_buf[PACKET_TAG_OFFSET]&=(~FRAME_HAS_ALIGN_ERRORS); local_packet_id++; i++; } printf("Main: sending process_buf=%p\n", process_buf); epicsMessageQueueSend(ptr_list, &process_buf, sizeof(&process_buf)); } free(buf); free(process_buf); scanf("%c%*c",&temp_char); return EXIT_SUCCESS; }
void* module_data_parser_thread(void* arg){ int is_autocal_data, reg_data,i,j,k,code_depth,err; unsigned short *local_buffer_ptr,*temp_us_ptr,*conv,*process_buf_ptr,*netbuffer,frame_header[HEADER_LENGHT]; unsigned short packet_tag,slot_id=0; unsigned char th_dac=0,loop_mode=0; unsigned short this_frame_has_aligment_errors; SOCKET data_socket; struct sockaddr_in sock_addr; int status; local_buffer_ptr=databuffer_allocation(PIXIEII_MODULES*MATRIX_DIM_WORDS*15);//la dimensione in byte di un intero frame if(local_buffer_ptr==NULL){ printf("PROC:error allocating buffers\n"); exit(-1);} else{ if(verbose>=2)printf("PROC:Processing Thread Started\n"); } /***TCP/IP monitor***************inizio********************dacounting_daq.cpp********************/ sock_addr.sin_family=AF_INET; // indico il protocollo utilizzato (TCP/IP) sock_addr.sin_port=htons(4444); //indico la porta a cui connettere il socket if (hostToIPAddr("127.0.0.1", &sock_addr.sin_addr) < 0) printf("PROC:hostToIPAddr failed\n"); // The following is not supported on Linux. Is it needed? //sock_addr.sin_addr.S_un.S_un_b.s_b1=127; // indico l'indirizzo IP //sock_addr.sin_addr.S_un.S_un_b.s_b2=0; //sock_addr.sin_addr.S_un.S_un_b.s_b3=0; //sock_addr.sin_addr.S_un.S_un_b.s_b4=1; netbuffer=databuffer_allocation((MATRIX_DIM_WORDS*PIXIEII_MODULES)+HEADER_LENGHT); /*****TCP/IP monitor****************fine********************dacounting_daq.cpp********************/ printf("PROC:data Parser Thread started\n"); conv=conversion_table_allocation(); while(1){ status = epicsMessageQueueReceive(ptr_list, &process_buf_ptr, sizeof(&process_buf_ptr)); printf("module_data_parser_thread: got process_buf_ptr=%p\n", process_buf_ptr); if (status <= 0){ printf("PROC: error epicsMessageQueueReceive returned %d\n", status); continue; } if (process_buf_ptr==NULL){ printf("PROC: error process_buf_ptr=NULL\n"); continue; } packet_tag=*(process_buf_ptr+PACKET_TAG_OFFSET*2); th_dac=(packet_tag>>(PIXIE_THDAC_OFFSET+DUMMY_0_OFFSET))&PIXIE_THDAC_MASK; loop_mode=(packet_tag>>(LOOP_MODE_OFFSET+DUMMY_1_OFFSET))&LOOP_MODE_MASK; if(verbose>=2)printf("\nPROC: packet_tag=%04xh\n",packet_tag); if(verbose>=2)printf("\nPROC: th_dac=%d, loop_mode=%02Xh\n",th_dac,loop_mode); slot_id=*((char*)process_buf_ptr+SLOT_ID_OFFSET)&SLOT_ID_MASK; if(verbose>=2)printf("PROC: slot_id=%04xh\n",slot_id); if(packet_tag & AUTOCAL_DATA){ if(verbose>=2)printf("\nPROC:Autocal"); code_depth=5; is_autocal_data=1; } else{ if(verbose>=2)printf("\nPROC:Counters"); code_depth=15; is_autocal_data=0; } if(packet_tag & REG_PACKET){ if(verbose>=2)printf("\nPROC:REG 1 data\n"); reg_data=1; } else{ if(verbose>=2)printf("\nPROC:REG 0 data\n"); reg_data=0; } if(packet_tag & FRAME_HAS_ALIGN_ERRORS){ this_frame_has_aligment_errors=1; } else{ this_frame_has_aligment_errors=0; } temp_us_ptr=process_buf_ptr+(PACKET_TAG_BYTES/2); if(verbose>=3)printf("local_buffer filling code_depth=%d\n",code_depth); for(i=0;i<PIXIEII_MODULES;i++) { for(j=0;j<COLS_PER_DOUT*PIXIE_ROWS;j++) { for(k=0;k<code_depth;k++){ my_bytes_swap(temp_us_ptr+i+(j*PIXIEII_MODULES*code_depth)+(k*PIXIEII_MODULES)); local_buffer_ptr[(i*COLS_PER_DOUT*PIXIE_ROWS*code_depth)+(j*code_depth)+k]= temp_us_ptr[i+(j*PIXIEII_MODULES*code_depth)+(k*PIXIEII_MODULES)]; } } } //printf("local_buffer has been filled with original data and data modules are grouped\n"); //memcpy(buff+PACKET_TAG_BYTES,process_buf_ptr+PACKET_TAG_BYTES,PIXIEII_MODULES*MATRIX_DIM_WORDS*code_depth); for(i=0;i<PIXIEII_MODULES;i++){ //printf("parsing %d module data\n",i); for(j=0;j<COLS_PER_DOUT*PIXIE_ROWS;j++) { convert_bit_stream_to_counts(code_depth, local_buffer_ptr+(i*COLS_PER_DOUT*PIXIE_ROWS*code_depth)+(j*code_depth), process_buf_ptr+(i*MATRIX_DIM_WORDS)+(j*PIXIE_DOUTS)+(PACKET_TAG_BYTES/2),PIXIE_DOUTS); } } //printf("data parsed\n"); for(i=0;i<PIXIEII_MODULES;i++){ //printf("processing module %d data\n,i); if(is_autocal_data==0 && convert_data==1) decode_pixie_data_buffer(conv,process_buf_ptr+(PACKET_TAG_BYTES/2)+i*MATRIX_DIM_WORDS); databuffer_sorting(process_buf_ptr+(PACKET_TAG_BYTES/2)+i*MATRIX_DIM_WORDS); map_data_buffer_on_pixie(process_buf_ptr+(PACKET_TAG_BYTES/2)+i*MATRIX_DIM_WORDS); } /*********************sendig data to TCPIP monitor*********************/ for(i=0;i<HEADER_LENGHT;i++) frame_header[i]=0x8000; frame_header[0]=BUFFER_HDR_TAG; frame_header[1]|=(unsigned short)(this_frame_has_aligment_errors); frame_header[2]|=(unsigned short)(is_autocal_data); frame_header[3]|=(sh_code & 0x1); frame_header[4]|=(unsigned short)ceil((double)shutter_duration_ms); frame_header[5]|=(unsigned short)slot_id; if(reg_data==0) frame_header[6]|=REG_0_BUFF_CODE; else frame_header[6]|=REG_1_BUFF_CODE; for(i=0;i<HEADER_LENGHT;i++) netbuffer[i]=frame_header[i]; for(i=0;i<MATRIX_DIM_WORDS*PIXIEII_MODULES;i++) netbuffer[i+HEADER_LENGHT]=process_buf_ptr[i+(PACKET_TAG_BYTES/2)]; data_socket=epicsSocketCreate(PF_INET,SOCK_STREAM,0); err=connect(data_socket,(struct sockaddr*)&sock_addr,sizeof(struct sockaddr)); if(!err) { if (verbose>=1)printf("\r\nI got Pixie!!"); } else if (verbose>=1)printf("\r\nGot error attempting to connect to pixie = %s",strerror(errno)); if(!err) send(data_socket,(const char*)netbuffer,(MATRIX_DIM*PIXIEII_MODULES)+(HEADER_LENGHT*2),0); if(!err)epicsSocketDestroy(data_socket); /*********************sendig data to TCPIP monitor*********************/ free(process_buf_ptr); if (verbose>=1)printf("PROC:pocessing buffer released\n"); } free(local_buffer_ptr);//qui non ci arriverà mai!!!! }