otsdaq-mu2e-stm  5.02.01
UDPsocket.hh
1 
5 #ifndef UDPSOCKET_hh
6 #define UDPSOCKET_hh
7 
8 // Hex reader
9 #include "STMDAQ-TestBeam/utils/dataVars.hh"
10 
11 // Logger
12 #include "STMDAQ-TestBeam/utils/Logger.hh"
13 
14 #include<iostream>
15 #include<fstream>
16 #include<vector>
17 
18 #include<string.h> //memset
19 #include<arpa/inet.h>
20 #include <sys/types.h>
21 #include<sys/socket.h>
22 #include <vector>
23 
24 #include <fcntl.h> // for open
25 #include <unistd.h> // for close
26 
27 #include <time.h>
28 #include <math.h>
29 
30 class UDPsocket {
31 
32 private:
33 
34  // The maximum udp datagram size
35  // Theoretical max = 65,535.
36  // Actual IPv4 max = (65,535 bytes − 8-byte UDP header − 20-byte IP header)
37  static const uint16_t MAX_UDP_SIZE = 65504;
38 
39  // SET THIS ON INITIALISATION LATER
40 
41  // The optimised SO_RCVBUF size
42  static const uint64_t RCVBUF_SZ = 268435456;
43  // The optimised SO_SNDBUF size
44  static const uint64_t SNDBUF_SZ = 268435456/2;
45 
46  // -------------
47 
48  // Recvfrom non-blocking timeout time
49  static const uint TIMEOUT_SECS = 0; // Secs
50  static const uint TIMEOUT_USECS = 500; // usecs
51  // The number of non-blocking timeouts to wait before exit
52  static const uint TIMEOUT_MAX = 5e4;
53 
54  // The last packet number
55  uint32_t last_packet[CHNUM] = {};
56 
57 public:
58 
59  // Standard constructor - should'nt be used
60  UDPsocket();
61 
62  // Kernel buffer sizes
63  uint64_t sock_mem = 0; // Total allocated socket memory
64  static const uint64_t SO_SNDBUF_SIZE = 0; // The set SO_SNDBUF size
65  // The number of packets to receive with sendmmsg
66  // The number of packets to receive with recvmmsg
67  static const int RECVMMSG_NUM = 65536;
68  //static const int RECVMMSG_NUM = RCVBUF_SZ/MAX_PACKET_SIZE;
69 
70  // static const int SENDMMSG_NUM = 512;
71  static const int SENDMMSG_NUM = RECVMMSG_NUM/1e2;
72 
73  // The maximum udp datagram length
74  static const uint16_t MAX_UDP_LEN = MAX_UDP_SIZE/2;
75 
76  // // The UDP packet to send/receice
77  int16_t packet[MAX_PACKET_LEN] = {};
78 
79  // The socket sevrer / client address
80  struct sockaddr_in servaddr, cliaddr;
81  fd_set readfds;
82  // The size of the client address
83  int slen = sizeof(cliaddr);
84  // The recv_from return value
85  int ret[CHNUM] = {};
86 
87  // The time value of the UDP timeout
88  struct timeval read_timeout;
89  // The UDP timeout counter
90  uint timeout_counter = 0;
91  // Boolean to signal if the UDP server has timed out
92  bool timeout = false;
93 
94  // Boolean to signal receiving multiple UDP datagrams
95  bool rcv_multiple = true;
96 
97  // Boolean whether this is the first packet of the data run
98  bool firstPacket = true;
99 
100  // Boolean whether each channel is receiving data
101  bool receiving_data[CHNUM] = {};
102 
103  // Check channel is only either 0 or 1
104  void check_channel(int CHAN){
105  if (CHAN != HPGE && CHAN != LABR){
106  // Kill program
107  Logger::Instance()->write(0,"Error! In UDPsocket::getIPaddress. ");
108  }
109  }
110 
111  // Check FW_or_SW is only either 0 (FW) or 1 (SW)
112  void check_fw_or_sw(int FW_or_SW){
113  if (FW_or_SW != FW && FW_or_SW != SW){
114  // Kill program
115  Logger::Instance()->write(0,"Error! In UDPsocket::check_recv_send. ");
116  }
117  }
118 
119  // Return the channel name
120  string get_channel_name(int CHAN){
121  // Check the channel number
122  check_channel(CHAN);
123  string chan;
124  if (CHAN==0){
125  chan = "HPGe";
126  }
127  else{
128  chan = "LaBr";
129  }
130  return chan;
131  }
132 
133  // Get the max UDP datagram size
134  uint16_t get_max_udp_size(){
135  return MAX_UDP_SIZE;
136  }
137 
138  // Set the stored last packet number
139  void setLastPacketNum(int chan, uint32_t lastPacket){
140  last_packet[chan] = lastPacket;
141  }
142 
143  // Get the stored last packet number
144  uint32_t getLastPacketNum(int chan){
145  return last_packet[chan];
146  }
147 
148 
149  // Get the maximum number of allowed UDP timeouts
150  uint getTimeoutMax(){
151  return TIMEOUT_MAX;
152  }
153 
154  // Socket error message function
155  void die(char *s){
156  perror(s);
157  exit(1);
158  }
159 
160  // Get socket IP address from xml file
161  std::string getIPaddress(int CHAN, int FW_or_SW);
162 
163  // Get socket port number from xml file
164  int getPort(int CHAN, int FW_or_SW);
165 
166  // Setup server to receive packets
167  int setupServer(int CHAN, int FW_or_SW);
168 
169  // Create UDP socket
170  int createSocket(int CHAN, int FW_or_SW);
171 
172  // Create UDP client
173  int setupClient(int CHAN, int FW_or_SW);
174 
175  // Bind socket to port
176  int bindSocket(int sock);
177 
178  // Set SO_RCVBUF size
179  int set_SO_RCVBUF(int sock, uint64_t size);
180 
181  // Set SO_SNDBUF size
182  int set_SO_SNDBUF(int sock, uint64_t size);
183 
184  // Set recvfrom non-blocking timeout
185  int setTimeout(int secs,double usecs);
186 
187  // Set buffer length
188  int setBufferLength();
189 
190  // Send SINGLE UDP datagram
191  int sendOne(int16_t* data, uint16_t size, int sock);
192 
193  // Send MULTIPLE UDP datagrams
194  int send(int16_t** data, uint16_t* size, int MSG_NUM, int sock);
195 
196  // Get SINGLE UDP datagram
197  int recvOne(int16_t* data, int sock, int CHAN);
198 
199  // Get MULTIPLE UDP datagrams
200  int recv(int16_t* data, int sock, int CHAN);
201 
202 };
203 
204 #endif
UDPsocket()
This module creates a UDP socket for 10G readout (main).
Definition: UDPsocket.cc:40
Definition: data.hh:4
Definition: queue.hh:10