#include <executables/split_headers.h> #include <sys/types.h> /* See NOTES */ #include <sys/socket.h> #include <netinet/in.h> #include <netinet/udp.h> int createListner (int port) { int sock; AssertFatal((sock=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) >= 0, ""); struct sockaddr_in addr = { sin_family: AF_INET, sin_port: htons(port), sin_addr: { s_addr: INADDR_ANY } }; int enable=1; AssertFatal(setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(enable))==0,""); AssertFatal(bind(sock, (const struct sockaddr *) &addr, sizeof(addr))==0,""); struct timeval tv= {0,UDP_TIMEOUT}; AssertFatal(setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO,&tv,sizeof(tv)) ==0,""); // Make a send/recv buffer larger than a a couple of subframe // so the kernel will store for us in and out paquets int buff=1000*1000*10; AssertFatal ( setsockopt(sock, SOL_SOCKET, SO_SNDBUF, &buff, sizeof(buff)) == 0, ""); AssertFatal ( setsockopt(sock, SOL_SOCKET, SO_RCVBUF, &buff, sizeof(buff)) == 0, ""); } // sock: udp socket // expectedTS: the expected timestamp, 0 if unknown // bufferZone: a reception area of bufferSize int receiveSubFrame(int sock, uint64_t expectedTS, void *bufferZone, int bufferSize) { int rcved=0; commonUDP_t *tmp=NULL; do { //read all subframe data from the control unit int ret=recv(sock, bufferZone, bufferSize, 0); if ( ret==-1) { if ( errno == EWOULDBLOCK || errno== EINTR ) { return rcved; // Timeout, subframe incomplete } else { LOG_E(HW,"Critical issue in socket: %s\n", strerror(errno)); return -1; } } else { tmp=(commonUDP_t *)bufferZone; if ( expectedTS && tmp->timestamp != expectedTS) { LOG_W(HW,"Received a paquet in mixed subframes, dropping it\n"); } else { rcved++; bufferZone+=ret; } } } while ( !rcved || rcved < tmp->nbBlocks ); return rcved; } int sendSubFrame(int sock, void *bufferZone, int nbBlocks) { do { int sz=alignedSize(bufferZone); int ret=send(sock, bufferZone, sz, 0); if ( ret != sz ) LOG_W(HW,"Wrote socket doesn't return size %d (val: %d, errno:%d)\n", sz, ret, errno); bufferZone+=sz; nbBlocks--; } while (nbBlocks); return 0; }