3 #include <sys/socket.h>
4 #include <netinet/in.h>
25 #define PARAM_SERVERADDR 1
26 #define BASE_PORT 5100
28 #define MAX_SENDENDPOINTS 10
31 // Turn on/off debugging
40 const int prio_to_ac[8] = {2,3,3,2,1,1,0,0};
41 const unsigned int ac_to_tos[4] = {224,160,96,64};
43 int ac_sockfd[AC_QUEUES];
47 const char logfname[] = "delay_stats.dat";
51 struct timespec send_timestamp;
52 unsigned long int seqn;
53 unsigned char padding[MTU];
56 /* maximal traffic delay in ms - 10 s*/
57 #define MAX_DELAY_US 10000000
58 #define GRANULARITY 100
60 unsigned delay_stats[AC_QUEUES][MAX_DELAY_US/GRANULARITY];
62 /*struct ac_stats[AC_QUEUES] {
63 unsigned long int min_trans_time;
64 unsigned long int sum_trans_time;
65 struct timespec recv_timestamp;
66 struct timespec send_timestamp;
69 struct send_endpoint {
72 int bandwidth_bps; /* bits per second */
75 #define MSEC (1000*1000)
76 #define Mbit (1024*1024)
81 struct send_endpoint sepoint[] = {
82 { .ac = AC_VO, .period_nsec=200*MSEC, .bandwidth_bps = 34*Kbit },
83 { .ac = AC_VI, .period_nsec=25*MSEC, .bandwidth_bps = 480*Kbit },
84 { .ac = AC_BE, .period_nsec=40*MSEC, .bandwidth_bps = 300*Kbit },
85 { .ac = AC_BK, .period_nsec=40*MSEC, .bandwidth_bps = 300*Kbit },
86 // { .ac = AC_VI, .period_nsec=17*MSEC, .bandwidth_bps = 675*Kbit },
90 struct send_endpoint sepoint[] = {
91 { .ac = AC_VO, .period_nsec=40*MSEC, .bandwidth_bps = 300*Kbit },
92 { .ac = AC_VI, .period_nsec=40*MSEC, .bandwidth_bps = 300*Kbit },
93 { .ac = AC_BE, .period_nsec=60*MSEC, .bandwidth_bps = 200*Kbit },
94 { .ac = AC_BK, .period_nsec=60*MSEC, .bandwidth_bps = 200*Kbit },
97 unsigned int nr_sepoints = sizeof(sepoint)/sizeof(*sepoint);
103 unsigned sum[AC_QUEUES];
105 printf("\n Writing data to log file...\n");
108 for (maxi = MAX_DELAY_US/GRANULARITY - 1; maxi >= 0; maxi--) {
109 for (ac = 0; ac < AC_QUEUES; ac++) {
110 if (delay_stats[ac][maxi] != 0) allzeros = false;
112 if (!allzeros) break;
114 if (maxi < 10000/GRANULARITY) maxi = 10000/GRANULARITY;
116 for (ac = 0; ac < AC_QUEUES; ac++) {
118 for ( i = 0 ; i < maxi; i++)
119 sum[ac]+=delay_stats[ac][i];
121 fprintf(stderr, "No response in AC %d\n", ac);
124 for (ac = 0; ac < AC_QUEUES; ac++) {
125 for ( i = 0 ; i < maxi; i++) {
127 val = (double)delay_stats[ac][i]*100.0 / sum[ac];
128 fprintf(logfd,"%f %lf\n", i*GRANULARITY/1000.0, val);
131 fprintf(logfd, "\n\n");
134 printf("Finished.\n");
141 void timespec_add (struct timespec *sum, const struct timespec *left,
142 const struct timespec *right)
144 sum->tv_sec = left->tv_sec + right->tv_sec;
145 sum->tv_nsec = left->tv_nsec + right->tv_nsec;
147 if (sum->tv_nsec >= 1000000000){
149 sum->tv_nsec -= 1000000000;
154 void timespec_sub (struct timespec *diff, const struct timespec *left,
155 const struct timespec *right)
157 diff->tv_sec = left->tv_sec - right->tv_sec;
158 diff->tv_nsec = left->tv_nsec - right->tv_nsec;
160 if (diff->tv_nsec < 0){
162 diff->tv_nsec += 1000000000;
166 int create_ac_socket(unsigned int ac)
169 unsigned int yes=1, tos;
172 if ((sockfd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
174 perror("Unable to open socket");
178 if (setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&yes,sizeof(int)) == -1) {
179 perror("Unable to set socket");
184 //tos = ((AC_QUEUES - ac) *2 - 1)*32;
186 if (setsockopt(sockfd, SOL_IP, IP_TOS, &tos, sizeof(tos))) {
187 perror("Unable to set TOS");
196 void* receiver(void* queue)
199 struct sockaddr_in rem_addr;
201 unsigned int ac, rem_addr_length;
202 unsigned long int trans_time_usec;
203 unsigned long int min_trans_time;
204 struct timespec send_timestamp,recv_timestamp, trans_time;
209 rem_addr_length = sizeof(rem_addr);
211 while ((mlen = recvfrom(ac_sockfd[ac], &msg, sizeof(msg), 0,\
212 (struct sockaddr*)&rem_addr, &rem_addr_length)) < 0) {
213 if (errno == EINTR) continue;
214 perror("Chyba pri prijimani pozadavku");
217 clock_gettime(CLOCK_MONOTONIC,&recv_timestamp);
218 send_timestamp = msg.send_timestamp;
220 timespec_sub(&trans_time,&recv_timestamp ,&send_timestamp);
221 trans_time_usec = (trans_time.tv_sec * 1000000 + \
222 trans_time.tv_nsec / 1000) /2;
224 if (trans_time_usec < MAX_DELAY_US)
225 delay_stats[ac][trans_time_usec/GRANULARITY]++;
227 /*if (trans_time_nsec < min_trans_time)
228 min_trans_time = trans_time_nsec;*/
229 /*printf("seqn= %lu tos= %d start= %lu(s).%lu(ns)"\
230 "stop= %lu(s).%lu(ns)\n trans_time = %lums\n",\
231 msg.seqn, msg.tos, send_timestamp.tv_sec,\
232 send_timestamp.tv_nsec,recv_timestamp.tv_sec,\
233 recv_timestamp.tv_nsec, trans_time_msec); */
237 void* sender(void* endpoint)
239 struct sockaddr_in rem_addr;
241 unsigned long int seqn;
242 struct timespec time_to_wait, current_time, period, interval;
244 struct send_endpoint* spoint = (struct send_endpoint*) endpoint;
247 memset(&rem_addr,0, sizeof(rem_addr));
248 //-------------------------------------------------------------------
249 // TODO: not functioning - check it
251 if ((rem_addr.sin_addr.s_addr = inet_addr(server_addr)) == INADDR_NONE){
252 ph = gethostbyname(server_addr);
254 rem_addr.sin_addr = *((struct in_addr *)ph->h_addr);
256 perror("Unknown server");
260 //------------------------------------------------------------------
262 rem_addr.sin_family = AF_INET;
263 rem_addr.sin_addr.s_addr = inet_addr(server_addr);
264 rem_addr.sin_port = htons(BASE_PORT + ac);
267 period.tv_nsec = spoint->period_nsec;
273 msg.tos = ac_to_tos[ac];
275 clock_gettime(CLOCK_MONOTONIC,&msg.send_timestamp);
277 while (sendto(ac_sockfd[ac], &msg, sizeof(msg), 0,\
278 (struct sockaddr*)&rem_addr, sizeof(rem_addr)) < 0) {
279 if (errno == EINTR) continue;
280 perror("Error while sending.");
290 timespec_add(&time_to_wait,&msg.send_timestamp,&period);
291 clock_gettime(CLOCK_MONOTONIC,¤t_time);
292 timespec_sub(&interval,&time_to_wait,¤t_time);
293 nanosleep(&interval,NULL);
297 int main(int argc, char *argv[])
306 while ((opt = getopt(argc, argv, "hs")) != -1) {
312 fprintf(stderr, "Usage: %s [ options ] server_addr\n", argv[0]);
313 fprintf(stderr, "options: -s read streams from stdin\n");
318 server_addr = argv[optind];
320 fprintf(stderr, "Expected server address argument\n");
326 memset(delay_stats,0, sizeof(delay_stats));
327 pthread_attr_init(&attr);
329 if ((logfd = fopen(logfname,"w+")) == NULL) {
330 fprintf(stderr,"Can not open %s\n", logfname);
335 if (signal(SIGTERM, stopper) == SIG_ERR) {
336 perror("Error in signal registration");
340 if (signal(SIGINT, stopper) == SIG_ERR) {
341 perror("Signal handler registration error");
345 /* create four receivers each per AC */
346 for (ac = AC_QUEUES - 1; ac >= 0; ac--) {
347 ac_sockfd[ac] = create_ac_socket(ac);
348 rc = pthread_create(&thread, &attr, receiver, (void*) ac);
350 printf("Error while creating receiver %d\n",rc);
355 /* create sendpoints */
356 for (i = 0; i < nr_sepoints; i++) {
357 rc = pthread_create(&thread, &attr, sender, (void*) &sepoint[i]);
359 printf("Error while creating sender %d\n",rc);