1 /*
2 * Copyright (C) 2017-2019 Alibaba Group Holding Limited
3 */
4
5 #include <stdio.h>
6 #include <stdlib.h>
7 #include <unistd.h>
8 #include <string.h>
9 #include "lwip/opt.h"
10 #include "iperf_wrapper.h"
11 #ifdef AOS_NETMGR_WITH_MODERN
12 #ifdef AOS_NET_WITH_WIFI
13 #include "wifi_service.h"
14 #endif /* AOS_NET_WITH_WIFI */
15 #endif /* AOS_NETMGR_WITH_MODERN */
16 #include "lwip/debug.h"
17 #include "lwip/sockets.h"
18 #include "lwip/apps/iperf_task.h"
19 #include "lwip/apps/iperf_debug.h"
20 #include "aos/cli.h"
21 /******************************************************
22 * Macros
23 ******************************************************/
24 #define IPERF_DEBUG_INTERNAL
25 #define DBGPRINT_IPERF(FEATURE, ...) do { \
26 if (g_iperf_debug_feature & FEATURE) { \
27 LWIP_DEBUGF( IPERF_DEBUG, (__VA_ARGS__)); \
28 } \
29 } while(0)
30
31 /******************************************************
32 * Constants
33 ******************************************************/
34
35 #define MAX_WIN_SIZE (1024*1024)
36
37 /* Private macro */
38 #define IPERF_DEFAULT_PORT 5001 //Port to listen
39
40 #define IPERF_HEADER_VERSION1 0x80000000
41 #define IPERF_DEFAULT_UDP_RATE (1024 * 1024)
42 #define IPERF_TEST_BUFFER_SIZE (2048)
43
44 /******************************************************
45 * Enumerations
46 ******************************************************/
47
48 /******************************************************
49 * Type Definitions
50 ******************************************************/
51
52 // Private typedef -------------------------------------------------------------
53 typedef struct count_s
54 {
55 unsigned Bytes;
56 unsigned KBytes;
57 unsigned MBytes;
58 unsigned GBytes;
59 unsigned times;
60 } count_t;
61
62 // used to reference the 4 byte ID number we place in UDP datagrams
63 // use int32_t if possible, otherwise a 32 bit bitfield (e.g. on J90)
64 typedef struct UDP_datagram
65 {
66 int32_t id;
67 unsigned int tv_sec;
68 unsigned int tv_usec;
69 } UDP_datagram;
70
71 /*
72 * The client_hdr structure is sent from clients
73 * to servers to alert them of things that need
74 * to happen. Order must be perserved in all
75 * future releases for backward compatibility.
76 * 1.7 has flags, num_threads, port, and buffer_len
77 */
78 typedef struct client_hdr
79 {
80 /*
81 * flags is a bitmap for different options
82 * the most significant bits are for determining
83 * which information is available. So 1.7 uses
84 * 0x80000000 and the next time information is added
85 * the 1.7 bit will be set and 0x40000000 will be
86 * set signifying additional information. If no
87 * information bits are set then the header is ignored.
88 * The lowest order diferentiates between dualtest and
89 * tradeoff modes, wheither the speaker needs to start
90 * immediately or after the audience finishes.
91 */
92 int32_t flags;
93 int32_t num_threads;
94 int32_t port;
95 int32_t buffer_len;
96 int32_t win_band;
97 int32_t amount;
98 } client_hdr;
99
100 /*
101 * The server_hdr structure facilitates the server
102 * report of jitter and loss on the client side.
103 * It piggy_backs on the existing clear to close
104 * packet.
105 */
106 typedef struct server_hdr
107 {
108 /*
109 * flags is a bitmap for different options
110 * the most significant bits are for determining
111 * which information is available. So 1.7 uses
112 * 0x80000000 and the next time information is added
113 * the 1.7 bit will be set and 0x40000000 will be
114 * set signifying additional information. If no
115 * information bits are set then the header is ignored.
116 */
117 int32_t flags;
118 int32_t total_len1;
119 int32_t total_len2;
120 int32_t stop_sec;
121 int32_t stop_usec;
122 int32_t error_cnt;
123 int32_t outorder_cnt;
124 int32_t datagrams;
125 int32_t jitter1;
126 int32_t jitter2;
127 } server_hdr;
128
129 /******************************************************
130 * Structures
131 ******************************************************/
132
133 /******************************************************
134 * Function Declarations
135 ******************************************************/
136
137 count_t iperf_calculate_result( int pkt_size, count_t pkt_count, int need_to_convert );
138 void iperf_display_report( char *report_title, unsigned time, unsigned h_ms_time, count_t pkt_count );
139 count_t iperf_reset_count( count_t pkt_count );
140 count_t iperf_copy_count( count_t pkt_count, count_t tmp_count );
141 count_t iperf_diff_count( count_t pkt_count, count_t tmp_count );
142 int iperf_format_transform( char *param );
143
144 /******************************************************
145 * Variables Definitions
146 ******************************************************/
147
148 uint32_t g_iperf_debug_feature = 0;
149 int g_iperf_is_tradeoff_test_client = 0;
150 int g_iperf_is_tradeoff_test_server = 0;
151 uint32_t g_iperf_server_addr = 0;
152
153 /******************************************************
154 * Function Definitions
155 ******************************************************/
156 /* members are in network byte order */
iperf_udp_run_server(char * parameters[])157 void iperf_udp_run_server( char *parameters[] )
158 {
159
160 int sockfd;
161 struct sockaddr_in servaddr;
162 struct sockaddr_in cliaddr;
163 int cli_len;
164 struct ip_mreq group;
165 int server_port;
166 int i;
167 count_t pkt_count = {0};
168 count_t tmp_count = {0};
169 int nbytes = 0; /* the number of read */
170 int total_send = 0; /* the total number of send */
171 int mcast_tag = 0; /* the tag of parameter "-B" */
172 int interval_tag = 0; /* the tag of parameter "-i" */
173 int interval_time = 10; /* the interval time of "-i" */
174 char *mcast;
175 #if defined(IPERF_DEBUG_ENABLE)
176 int send_bytes = 0; /* the number of send */
177 int tmp = 0;
178 #endif
179 char *buffer = (char*) iperf_wrapper_malloc( IPERF_TEST_BUFFER_SIZE );
180
181 uint32_t t1 = 0;
182 uint32_t t2 = 0;
183 uint32_t curr_t = 0;
184 uint32_t curr_h_ms = 0;
185 uint32_t t2_h_ms = 0;
186 uint32_t t1_h_ms = 0;
187 uint32_t tmp_t = 0;
188 uint32_t tmp_h_ms = 0;
189 uint32_t offset_t1 = 0;
190 uint32_t offset_t2 = 0;
191 uint32_t offset_time = 0;
192 UDP_datagram *udp_h = NULL;
193 client_hdr *client_h = NULL;
194 client_hdr client_h_trans = {0};
195 struct timeval timeout = {0};
196 timeout.tv_sec = 20; //set recvive timeout = 20(sec)
197 int is_test_started = 0;
198 int udp_h_id = 0;
199
200 memset( buffer, 0, IPERF_TEST_BUFFER_SIZE );
201 //Statistics init
202 pkt_count = iperf_reset_count( pkt_count );
203 tmp_count = iperf_reset_count( tmp_count );
204 server_port = 0;
205 t1 = 0;
206 t2 = 0;
207 int offset = IPERF_COMMAND_BUFFER_SIZE / sizeof(char *);
208
209 //Handle input parameters
210 if ( g_iperf_is_tradeoff_test_client == 0 ) {
211 for ( i = 0; i < 13; i++ ) {
212 if ( strcmp( (char *) ¶meters[i * offset], "-p" ) == 0 ) {
213 i++;
214 server_port = atoi( (char *) ¶meters[i * offset] );
215 } else if ( strcmp( (char *) ¶meters[i * offset], "-n" ) == 0 ) {
216 i++;
217 total_send = iperf_format_transform( (char *) ¶meters[i * offset] );
218 LWIP_DEBUGF( IPERF_DEBUG, ("Set number to transmit = %d Bytes\n", total_send ));
219 } else if ( strcmp( (char *) ¶meters[i * offset], "-B" ) == 0 ) {
220 i++;
221 mcast = (char *) ¶meters[i * offset];
222 mcast_tag = 1;
223 LWIP_DEBUGF( IPERF_DEBUG, ("Join Multicast %s\n", mcast) );
224 } else if ( strcmp( (char *) ¶meters[i * offset], "-i" ) == 0 ) {
225 interval_tag = 1;
226 i++;
227 if((interval_time = atoi((char*) ¶meters[i * offset])) == 0) {
228 interval_time = 10;
229 i--;
230 }
231 LWIP_DEBUGF( IPERF_DEBUG, ( "Set %d seconds between periodic bandwidth reports\n" , interval_time));
232 }
233 }
234 }
235
236 // Create a new UDP connection handle
237 if ( (sockfd = lwip_socket( AF_INET, SOCK_DGRAM, 0 )) < 0 ) {
238 LWIP_DEBUGF( IPERF_DEBUG, ("[%s:%d] sockfd = %d\n", __FUNCTION__, __LINE__, sockfd ));
239 if ( parameters ) {
240 iperf_wrapper_free( parameters );
241 }
242 aos_task_exit(0);
243 return;
244 }
245
246 // Bind to port and any IP address
247 memset( &servaddr, 0, sizeof(servaddr) );
248 servaddr.sin_family = AF_INET;
249 servaddr.sin_addr.s_addr = htonl( INADDR_ANY );
250 if ( server_port == 0 ) {
251 servaddr.sin_port = htons( IPERF_DEFAULT_PORT );
252 LWIP_DEBUGF( IPERF_DEBUG, ("Default server port = %d\n", IPERF_DEFAULT_PORT ));
253 } else {
254 servaddr.sin_port = htons( server_port );
255 LWIP_DEBUGF( IPERF_DEBUG, ("Set server port = %d\n", server_port ));
256 }
257
258 //Multicast settings
259 if ( mcast_tag == 1 ) {
260 group.imr_multiaddr.s_addr = inet_addr( mcast );
261 group.imr_interface.s_addr = htonl( INADDR_ANY );
262
263 if ( lwip_setsockopt( sockfd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *) &group, sizeof(struct ip_mreq) ) < 0 ) {
264 LWIP_DEBUGF( IPERF_DEBUG, ("Setsockopt failed - multicast settings\n" ));
265 }
266 }
267
268 if ( (lwip_bind( sockfd, (struct sockaddr *) &servaddr, sizeof(servaddr) )) < 0 ) {
269 LWIP_DEBUGF( IPERF_DEBUG, ("[%s:%d]\n", __FUNCTION__, __LINE__ ));
270 if ( parameters ) {
271 iperf_wrapper_free( parameters );
272 }
273 lwip_close(sockfd);
274 aos_task_exit(0);
275 return;
276 }
277
278 socklen_t len = sizeof(timeout);
279 if ( lwip_setsockopt( sockfd, SOL_SOCKET, SO_RCVTIMEO, (char *) &timeout, len ) < 0 ) {
280 LWIP_DEBUGF( IPERF_DEBUG, ("Setsockopt failed - cancel receive timeout\n" ));
281 }
282
283 cli_len = sizeof(cliaddr);
284
285 // Wait and check the request
286 do {
287 // Handles request
288 do {
289 iperf_get_current_time( &offset_t1, 0 );
290 nbytes = lwip_recvfrom( sockfd, buffer, IPERF_TEST_BUFFER_SIZE, 0, (struct sockaddr *) &cliaddr,
291 (socklen_t *) &cli_len );
292 iperf_get_current_time( &offset_t2, 0 );
293
294 //if connected to iperf v2.0.1, there is no end package sent from client side
295 if ( (offset_t2 > (offset_t1 + 2)) && (nbytes <= 0) && (pkt_count.times >= 1) ) {
296 offset_time = offset_t2 - offset_t1;
297 } else if ( offset_time != 0 ) {
298 offset_time = 0;
299 }
300
301 udp_h = (UDP_datagram *) buffer;
302 udp_h_id = (int) ntohl( udp_h->id );
303
304 #if defined(IPERF_DEBUG_INTERNAL)
305 client_h = (client_hdr *)&buffer[12];
306 client_h_trans.flags = (int32_t)(ntohl(client_h->flags));
307 client_h_trans.num_threads = (int32_t)(ntohl(client_h->num_threads));
308 client_h_trans.port = (int32_t)(ntohl(client_h->port));
309 client_h_trans.buffer_len = (int32_t)(ntohl(client_h->buffer_len));
310 client_h_trans.win_band = (int32_t)(ntohl(client_h->win_band));
311 client_h_trans.amount = (int32_t)(ntohl(client_h->amount));
312
313 DBGPRINT_IPERF(IPERF_DEBUG_RECEIVE, "UDP server, receive from sockfd \"%d\", id is \"%d\", tv_sec is \"%"U32_F"\", tv_usec is \"%"U32_F"\", nbytes is \"%d\"",
314 sockfd, udp_h_id, ntohl(udp_h->tv_sec), ntohl(udp_h->tv_usec), nbytes);
315 DBGPRINT_IPERF(IPERF_DEBUG_RECEIVE, "UDP server, receive from sin_len = %d, sin_family = %d , port = %d, s_addr = 0x%"X32_F"", cliaddr.sin_len, cliaddr.sin_family,
316 cliaddr.sin_port, cliaddr.sin_addr.s_addr);
317 DBGPRINT_IPERF(IPERF_DEBUG_RECEIVE, "[%s:%d] t1 = %"U32_F", t2 = %"U32_F"", __FUNCTION__, __LINE__, t1, t2);
318
319 DBGPRINT_IPERF(IPERF_DEBUG_RECEIVE, "[%s:%d], client_h_trans.flag = %d, num_threads = %d, port = %d, buffer_len = %d, win_band = %d, amount = %d"
320 , __FUNCTION__, __LINE__, client_h_trans.flags, client_h_trans.num_threads, client_h_trans.port, client_h_trans.buffer_len, client_h_trans.win_band, client_h_trans.amount);
321 #endif
322
323 #if defined(IPERF_DEBUG_ENABLE)
324 if (tmp != nbytes) {
325 DBGPRINT_IPERF(IPERF_DEBUG_RECEIVE, "[%s:%d] nbytes=%d ", __FUNCTION__, __LINE__, nbytes);
326 } else {
327 DBGPRINT_IPERF(IPERF_DEBUG_RECEIVE, ".");
328 }
329 tmp = nbytes;
330 #endif
331
332 pkt_count = iperf_calculate_result( nbytes, pkt_count, 0 );
333
334 if ( pkt_count.times == 1 ) {
335 iperf_get_current_time( &t1, &t1_h_ms );
336 t1_h_ms = (t1_h_ms / 100) % interval_time;
337 }
338
339 // Report by second
340 if ( (pkt_count.times >= 1 && interval_tag > 0) ) {
341 iperf_get_current_time( &curr_t, &curr_h_ms );
342 curr_h_ms = (curr_h_ms / 100) % interval_time;
343
344 if ( offset_time > 0 ) {
345 curr_t -= offset_time;
346 }
347
348 if ( curr_h_ms >= t1_h_ms ) {
349 tmp_h_ms = curr_h_ms - t1_h_ms;
350 tmp_t = curr_t - t1;
351 } else {
352 tmp_h_ms = curr_h_ms + interval_time - t1_h_ms;
353 tmp_t = curr_t - t1 - 1;
354 }
355
356 if ( (((int)(curr_t - t1) / interval_time) == interval_tag) && ((curr_h_ms >= t1_h_ms) || ((curr_t - t1) % 10) >= 1) ) {
357 aos_cli_printf("Interval: %d.0 - %d.0 sec ", (int) (curr_t - t1) / interval_time * interval_time - interval_time,
358 (int) (curr_t - t1) / interval_time * interval_time );
359 iperf_display_report( "UDP Server", interval_time, 0, iperf_diff_count( pkt_count, tmp_count ) );
360 tmp_count = iperf_copy_count( pkt_count, tmp_count );
361 interval_tag++;
362 } else if ( ((udp_h_id < 0) || (nbytes <= 0)) && (((tmp_t) % interval_time) != 0) && (is_test_started == 1) ) {
363 aos_cli_printf("Interval: %d.0 - %d.%d sec ", (int) (curr_t - t1 + 1) / interval_time * interval_time - interval_time,
364 (int) tmp_t, (int) tmp_h_ms );
365 iperf_display_report( "UDP Server", (tmp_t - ((curr_t - t1 + 1) / interval_time * interval_time - interval_time)), tmp_h_ms,
366 iperf_diff_count( pkt_count, tmp_count ) );
367 tmp_count = iperf_copy_count( pkt_count, tmp_count );
368 interval_tag++;
369 }
370 }
371
372 if ( (is_test_started == 0) && (udp_h_id > 0) && (nbytes > 0) ) {
373 is_test_started = 1;
374 } else if ( ((udp_h_id < 0) || (nbytes <= 0)) && (is_test_started == 1) ) { // the last package
375 int32_t old_flag = 0;
376
377 // test end, save the current time to "t2"
378 if ( pkt_count.times >= 1 ) {
379 /* sync the time if report by second */
380 if ( interval_tag > 0 ) {
381 t2 = curr_t;
382 t2_h_ms = curr_h_ms;
383 } else {
384 iperf_get_current_time( &t2, &t2_h_ms );
385 t2_h_ms = (t2_h_ms / 100) % interval_time;
386 if ( offset_time > 0 ) {
387 t2 -= offset_time;
388 }
389 }
390 }
391
392 // Calculate time: second
393 if ( t2_h_ms >= t1_h_ms ) {
394 t2_h_ms = t2_h_ms - t1_h_ms;
395 t2 = t2 - t1;
396 } else {
397 t2_h_ms = t2_h_ms + interval_time - t1_h_ms;
398 t2 = t2 - t1 - 1;
399 }
400 // print out result
401 iperf_display_report( "[Total]UDP Server", t2, t2_h_ms, pkt_count );
402
403 //TODO: need to send the correct report to client-side, flag = 0 means the report is ignored.
404 if ( udp_h_id < 0 ) {
405 old_flag = client_h_trans.flags;
406 client_h_trans.flags = (int32_t) 0;
407
408 // send the server report to client-side
409 #if defined(IPERF_DEBUG_ENABLE)
410 send_bytes =
411 #endif
412 lwip_sendto( sockfd, buffer, nbytes, 0, (struct sockaddr *) &cliaddr, cli_len );
413 client_h_trans.flags = old_flag;
414 }
415
416 #if defined(IPERF_DEBUG_ENABLE)
417 DBGPRINT_IPERF(IPERF_DEBUG_RECEIVE, "[%s:%d]send_bytes = %d, nbytes = %d,", __FUNCTION__, __LINE__, send_bytes, nbytes);
418 #endif
419
420 client_h = (client_hdr *) &buffer[12];
421 client_h_trans.flags = (int32_t) (ntohl( client_h->flags ));
422
423 // Tradeoff mode
424 if ( IPERF_HEADER_VERSION1 & client_h_trans.flags ) {
425 LWIP_DEBUGF( IPERF_DEBUG, ("Tradeoff mode, client-side start.\n" ));
426
427 g_iperf_is_tradeoff_test_server = 1;
428 g_iperf_server_addr = cliaddr.sin_addr.s_addr;
429 iperf_udp_run_client( NULL );
430 g_iperf_is_tradeoff_test_server = 0;
431
432 }
433
434 LWIP_DEBUGF( IPERF_DEBUG, ("Data transfer is finished.\n" ));
435 //TODO: send report to other side
436 break;
437 }
438 } while ( nbytes > 0 );
439
440 #if defined(IPERF_DEBUG_ENABLE)
441 DBGPRINT_IPERF(IPERF_DEBUG_RECEIVE, "[%s:%d] Interval = %"U32_F".%"U32_F" (secs)", __FUNCTION__, __LINE__, t2, t2_h_ms); //sec.
442 #endif
443
444 } while ( 0 );
445
446 LWIP_DEBUGF( IPERF_DEBUG, (" UDP server close socket!\n" ));
447 lwip_close( sockfd );
448
449 LWIP_DEBUGF( IPERF_DEBUG, ("If you want to execute iperf server again, please enter \"iperf -s -u\".\n" ));
450
451 if ( parameters ) {
452 iperf_wrapper_free( parameters );
453 }
454 iperf_wrapper_free( buffer );
455 // For tradeoff mode, task will be deleted in iperf_udp_run_client
456 if ( g_iperf_is_tradeoff_test_client == 0 ) {
457 aos_task_exit(0);
458 return;
459 }
460 }
461
iperf_tcp_run_server(char * parameters[])462 void iperf_tcp_run_server( char *parameters[] )
463 {
464 int listenfd, connfd;
465 struct sockaddr_in servaddr, cliaddr;
466 socklen_t clilen;
467 int server_port;
468 int i;
469 count_t pkt_count = {0};
470 count_t tmp_count = {0};
471 int nbytes = 0; /* the number of read */
472 int total_rcv = 0; /* the total number of receive */
473 int num_tag = 0; /* the tag of parameter "-n" */
474 int interval_tag = 0; /* the tag of parameter "-i" */
475 int interval_time = 10; /* the interval time of "-i" */
476 #if defined(IPERF_DEBUG_ENABLE)
477 int tmp = 0;
478 #endif
479 uint32_t t1, t2, curr_t;
480 int offset = IPERF_COMMAND_BUFFER_SIZE / sizeof(char *);
481 char *buffer = (char*) iperf_wrapper_malloc( IPERF_TEST_BUFFER_SIZE );
482 struct timeval timeout = {0};
483 timeout.tv_sec = 20; //set recvive timeout = 20(sec)
484
485 memset( buffer, 0, IPERF_TEST_BUFFER_SIZE );
486 //Statistics init
487 pkt_count = iperf_reset_count( pkt_count );
488 tmp_count = iperf_reset_count( tmp_count );
489 server_port = 0;
490
491 //Handle input parameters
492 for ( i = 0; i < 9; i++ ) {
493 if ( strcmp( (char *) ¶meters[i * offset], "-p" ) == 0 ) {
494 i++;
495 server_port = atoi( (char *) ¶meters[i * offset] );
496 } else if ( strcmp( (char *) ¶meters[i * offset], "-n" ) == 0 ) {
497 i++;
498 total_rcv = iperf_format_transform( (char *) ¶meters[i * offset] );
499 num_tag = 1;
500 LWIP_DEBUGF( IPERF_DEBUG, ("Set number to receive = %d Bytes\n", total_rcv ));
501 } else {
502 if ( strcmp( (char *) ¶meters[i * offset], "-i" ) == 0 ) {
503 interval_tag = 1;
504 i++;
505 if((interval_time = atoi((char*) ¶meters[i * offset])) == 0) {
506 interval_time = 10;
507 i--;
508 }
509 LWIP_DEBUGF( IPERF_DEBUG, ( "Set %d seconds between periodic bandwidth reports\n" , interval_time));
510 }
511 }
512 }
513
514 // Create a new TCP connection handle
515 if ( (listenfd = lwip_socket( AF_INET, SOCK_STREAM, 0 )) < 0 ) {
516 LWIP_DEBUGF( IPERF_DEBUG, ("[%s:%d] listenfd = %d\n", __FUNCTION__, __LINE__, listenfd ));
517 if ( parameters ) {
518 iperf_wrapper_free( parameters );
519 }
520 aos_task_exit(0);
521 return;
522 }
523
524 do {
525 // Bind to port and any IP address
526 memset( &servaddr, 0, sizeof(servaddr) );
527 servaddr.sin_family = AF_INET;
528 servaddr.sin_addr.s_addr = htonl( INADDR_ANY );
529 if ( server_port == 0 ) {
530 servaddr.sin_port = htons( IPERF_DEFAULT_PORT );
531 LWIP_DEBUGF( IPERF_DEBUG, ("Default server port = %d\n", IPERF_DEFAULT_PORT ));
532 }
533 else {
534 servaddr.sin_port = htons( server_port );
535 LWIP_DEBUGF( IPERF_DEBUG, ("Set server port = %d\n", server_port ));
536 }
537
538 if ( (lwip_bind( listenfd, (struct sockaddr *) &servaddr, sizeof(servaddr) )) < 0 ) {
539 LWIP_DEBUGF( IPERF_DEBUG, ("[%s:%d] \n", __FUNCTION__, __LINE__ ));
540 break;
541 }
542
543 // Put the connection into LISTEN state
544 if ( (lwip_listen( listenfd, 1024 )) < 0 ) {
545 LWIP_DEBUGF( IPERF_DEBUG, ("[%s:%d] \n", __FUNCTION__, __LINE__ ));
546 break;
547 }
548
549 int buflen = 64240;
550 if ( lwip_setsockopt( listenfd, SOL_SOCKET, SO_RCVBUF, (char *) &buflen, sizeof(buflen) ) < 0 ) {
551 LWIP_DEBUGF( IPERF_DEBUG, ("Setsockopt failed - cancel receive buf len\n" ));
552 }
553
554 do {
555 if ( server_port != 0 ) {
556 LWIP_DEBUGF( IPERF_DEBUG, ("Listen...(port = %d)\n", server_port ));
557 } else {
558 LWIP_DEBUGF( IPERF_DEBUG, ("Listen...(port = %d)\n", IPERF_DEFAULT_PORT ));
559 }
560 // Block and wait for an incoming connection
561 if ( (connfd = lwip_accept( listenfd, (struct sockaddr *) &cliaddr, &clilen )) != -1 ) {
562 socklen_t len = sizeof(timeout);
563
564 LWIP_DEBUGF( IPERF_DEBUG, ("[%s:%d] Accept... (sockfd=%d)\n", __FUNCTION__, __LINE__, connfd ));
565 if ( lwip_setsockopt( connfd, SOL_SOCKET, SO_RCVTIMEO, (char *) &timeout, len ) < 0 ) {
566 LWIP_DEBUGF( IPERF_DEBUG, ("Setsockopt failed - cancel receive timeout\n" ));
567 }
568
569 //Connection
570 do {
571 nbytes = lwip_recv( connfd, buffer, IPERF_TEST_BUFFER_SIZE, 0 );
572 pkt_count = iperf_calculate_result( nbytes, pkt_count, 0 );
573 if ( pkt_count.times == 1 ) {
574 iperf_get_current_time( &t1, 0 );
575 }
576 #if defined(IPERF_DEBUG_ENABLE)
577 if (tmp != nbytes) {
578 DBGPRINT_IPERF(IPERF_DEBUG_RECEIVE, "[%s:%d] nbytes=%d ", __FUNCTION__, __LINE__, nbytes);
579 } else {
580 DBGPRINT_IPERF(IPERF_DEBUG_RECEIVE, ".");
581 }
582 tmp = nbytes;
583 #endif
584 if ( num_tag == 1 ) {
585 total_rcv -= nbytes;
586 }
587
588 //Reach total receive number "-n"
589 if ( total_rcv < 0 ) {
590 LWIP_DEBUGF( IPERF_DEBUG, ("Finish Receiving\n" ));
591 break;
592 }
593 if ( pkt_count.times >= 1 && interval_tag > 0 ) {
594 iperf_get_current_time( &curr_t, 0 );
595 if ( ((int)(curr_t - t1) / interval_time) == interval_tag ) {
596 aos_cli_printf("Interval: %d - %d sec ", (int) (curr_t - t1) / interval_time * interval_time - interval_time,
597 (int) (curr_t - t1) / interval_time * interval_time );
598 iperf_display_report( "TCP Server", interval_time, 0, iperf_diff_count( pkt_count, tmp_count ) );
599 tmp_count = iperf_copy_count( pkt_count, tmp_count );
600 interval_tag++;
601 }
602 }
603 } while ( nbytes > 0 );
604
605 if ( pkt_count.times >= 1 ) {
606 iperf_get_current_time( &t2, 0 );
607 }
608
609 LWIP_DEBUGF( IPERF_DEBUG, ("Close socket!\n" ));
610 //Get report
611 iperf_display_report( "[Total]TCP Server", t2 - t1, 0, pkt_count );
612
613 //Statistics init
614 pkt_count = iperf_reset_count( pkt_count );
615 tmp_count = iperf_reset_count( tmp_count );
616 if ( interval_tag > 0 ) {
617 interval_tag = 1;
618 } else {
619 interval_tag = 0;
620 }
621 lwip_close( connfd );
622 }
623 } while ( connfd != -1 && num_tag == 0 );
624
625 if ( num_tag == 0 ) {
626 LWIP_DEBUGF( IPERF_DEBUG, ("Close socket!\n" ));
627 iperf_display_report( "[Total]TCP Server ", t2 - t1, 0, pkt_count );
628 }
629 } while ( 0 ); //Loop just once
630
631 lwip_close( listenfd );
632 LWIP_DEBUGF( IPERF_DEBUG, ("If you want to execute iperf server again, please enter \"iperf -s\".\n" ));
633
634 if ( parameters ) {
635 iperf_wrapper_free( parameters );
636 }
637
638 iperf_wrapper_free( buffer );
639 aos_task_exit(0);
640 return;
641 }
642
iperf_tcp_run_client(char * parameters[])643 void iperf_tcp_run_client( char *parameters[] )
644 {
645 int sockfd;
646 struct sockaddr_in servaddr;
647 char *Server_IP;
648 count_t pkt_count = {0};
649 count_t tmp_count = {0};
650 int nbytes = 0; /* the number of send */
651 int total_send = 0; /* the total number of transmit */
652 int num_tag = 0; /* the tag of parameter "-n" */
653 int interval_tag = 0; /* the tag of parameter "-i" */
654 int interval_time = 10; /* the interval time of "-i" */
655 int i;
656 int win_size, send_time, server_port, pkt_delay, tos;
657 uint32_t t1, t2, curr_t;
658 int offset = IPERF_COMMAND_BUFFER_SIZE / sizeof(char *);
659 char *buffer = (char*) iperf_wrapper_malloc( IPERF_TEST_BUFFER_SIZE );
660 pkt_count = iperf_reset_count( pkt_count );
661 tmp_count = iperf_reset_count( tmp_count );
662 win_size = 0;
663 send_time = 0;
664 server_port = 0;
665 pkt_delay = 0;
666 tos = 0;
667 memset( buffer, 0, IPERF_TEST_BUFFER_SIZE );
668 //Handle input parameters
669 Server_IP = (char *) ¶meters[0];
670
671 LWIP_DEBUGF( IPERF_DEBUG, ("Servr IP %s \n", Server_IP ));
672 for ( i = 1; i < 18; i++ ) {
673 if ( strcmp( (char *) ¶meters[i * offset], "-w" ) == 0 ) {
674 i++;
675 win_size = iperf_format_transform( (char *) ¶meters[i * offset] );
676 if ( win_size > MAX_WIN_SIZE ) {
677 LWIP_DEBUGF( IPERF_DEBUG, ("Win size too big, set to %d \n", MAX_WIN_SIZE ));
678 win_size = MAX_WIN_SIZE;
679 }
680 LWIP_DEBUGF( IPERF_DEBUG, ("Set window size = %d Bytes\n", win_size ));
681 }
682
683 else if ( strcmp( (char *) ¶meters[i * offset], "-t" ) == 0 ) {
684 i++;
685 send_time = atoi( (char *) ¶meters[i * offset] );
686 LWIP_DEBUGF( IPERF_DEBUG, ("Set send times = %d (secs)\n", atoi( (char *) ¶meters[i * offset] ) ));
687 }
688 else if ( strcmp( (char *) ¶meters[i * offset], "-p" ) == 0 ) {
689 i++;
690 server_port = atoi( (char *) ¶meters[i * offset] );
691 }
692 else if ( strcmp( (char *) ¶meters[i * offset], "-d" ) == 0 ) {
693 i++;
694 pkt_delay = atoi( (char *) ¶meters[i * offset] );
695 LWIP_DEBUGF( IPERF_DEBUG, ("Set packet delay = %d (ms)\n", atoi( (char *) ¶meters[i * offset] ) ));
696 } else if ( strcmp( (char *) ¶meters[i * offset], "-n" ) == 0 ) {
697 i++;
698 total_send = iperf_format_transform( (char *) ¶meters[i * offset] );
699 num_tag = 1;
700 LWIP_DEBUGF( IPERF_DEBUG, ("Set number to transmit = %d Bytes\n", total_send ));
701 } else if ( strcmp( (char *) ¶meters[i * offset], "-S" ) == 0 ) {
702 i++;
703 tos = atoi( (char *) ¶meters[i * offset] );
704 LWIP_DEBUGF( IPERF_DEBUG, ("Set TOS = %d\n", atoi( (char *) ¶meters[i * offset] ) ));
705 } else if ( strcmp( (char *) ¶meters[i * offset], "-i" ) == 0 ) {
706 interval_tag = 1;
707 i++;
708 if((interval_time = atoi((char*) ¶meters[i * offset])) == 0) {
709 interval_time = 10;
710 i--;
711 }
712 LWIP_DEBUGF( IPERF_DEBUG, ( "Set %d seconds between periodic bandwidth reports\n" , interval_time));
713 }
714 }
715
716 if ( win_size == 0 ) {
717 win_size = 1460;
718 LWIP_DEBUGF( IPERF_DEBUG, ("Default window size = %d Bytes\n", win_size ));
719 }
720 if ( send_time == 0 ) {
721 if ( num_tag == 1 ) {
722 send_time = 999999;
723 }
724 else {
725 send_time = 10;
726 LWIP_DEBUGF( IPERF_DEBUG, ("Default send times = %d (secs)\n", send_time ));
727 }
728 }
729
730 // Create a new TCP connection handle
731 if ( (sockfd = lwip_socket( AF_INET, SOCK_STREAM, 0 )) < 0 ) {
732 LWIP_DEBUGF( IPERF_DEBUG, ("[%s:%d] sockfd = %d\n", __FUNCTION__, __LINE__, sockfd ));
733 if ( parameters ) {
734 iperf_wrapper_free( parameters );
735 }
736 aos_task_exit(0);
737 return;
738 }
739
740 if ( lwip_setsockopt( sockfd, IPPROTO_IP, IP_TOS, &tos, sizeof(tos) ) < 0 ) {
741 LWIP_DEBUGF( IPERF_DEBUG, ("Set TOS: fail!\n" ));
742 }
743 // Bind to port and IP
744 memset( &servaddr, 0, sizeof(servaddr) );
745 servaddr.sin_family = AF_INET;
746 servaddr.sin_addr.s_addr = inet_addr( Server_IP );
747 if ( server_port == 0 ) {
748 servaddr.sin_port = htons( IPERF_DEFAULT_PORT );
749 LWIP_DEBUGF( IPERF_DEBUG, ("Default server port = %d\n", IPERF_DEFAULT_PORT ));
750 } else {
751 servaddr.sin_port = htons( server_port );
752 LWIP_DEBUGF( IPERF_DEBUG, ("Set server port = %d\n", server_port ));
753 }
754
755 if ( (lwip_connect( sockfd, (struct sockaddr *) &servaddr, sizeof(servaddr) )) < 0 ) {
756 LWIP_DEBUGF( IPERF_DEBUG, ("Connect failed, sockfd is %d, addr is \"%s\"\n", (int) sockfd,
757 ((struct sockaddr *) &servaddr)->sa_data ));
758 lwip_close( sockfd );
759 if ( parameters ) {
760 iperf_wrapper_free( parameters );
761 }
762 aos_task_exit(0);
763 return;
764 }
765
766 iperf_get_current_time( &t1, 0 );
767
768 do {
769 nbytes = lwip_send( sockfd, buffer, win_size, 0 );
770 if (nbytes < 0) {
771 LWIP_DEBUGF( IPERF_DEBUG, ("Send failed\n" ));
772 break;
773 }
774
775 pkt_count = iperf_calculate_result( nbytes, pkt_count, 0 );
776 #if defined(IPERF_DEBUG_ENABLE)
777 DBGPRINT_IPERF(IPERF_DEBUG_SEND, "[%s:%d]nbytes=%d ", __FUNCTION__, __LINE__, nbytes);
778 #endif
779 aos_msleep( pkt_delay );
780
781 if ( num_tag == 1 ) {
782 total_send -= nbytes;
783 }
784 //Reach total receive number "-n"
785 if ( total_send < 0 ) {
786 LWIP_DEBUGF( IPERF_DEBUG, ("Finish Sending\n" ));
787 break;
788 }
789
790 if ( interval_tag > 0 ) {
791 iperf_get_current_time( &curr_t, 0 );
792
793 if ( ((int)(curr_t - t1) / interval_time) == interval_tag ) {
794 aos_cli_printf("Interval: %d - %d sec ", (int) (curr_t - t1) / interval_time * interval_time - interval_time,
795 (int) (curr_t - t1) / interval_time * interval_time );
796 iperf_display_report( "TCP Client", interval_time, 0, iperf_diff_count( pkt_count, tmp_count ) );
797 tmp_count = iperf_copy_count( pkt_count, tmp_count );
798 interval_tag++;
799 }
800 }
801
802 iperf_get_current_time( &curr_t, 0 );
803 } while ( (int)(curr_t - t1) < send_time );
804
805 iperf_get_current_time( &t2, 0 );
806
807 lwip_close( sockfd );
808 LWIP_DEBUGF( IPERF_DEBUG, ("Close socket!\n" ));
809 iperf_wrapper_free( buffer );
810 iperf_display_report( "[Total]TCP Client", t2 - t1, 0, pkt_count );
811
812 if ( parameters ) {
813 iperf_wrapper_free( parameters );
814 }
815 aos_task_exit(0);
816 return;
817 }
818
iperf_udp_run_client(char * parameters[])819 void iperf_udp_run_client( char *parameters[] )
820 {
821 int sockfd;
822 struct sockaddr_in servaddr;
823 char *Server_IP = 0;
824 count_t pkt_count = {0};
825 count_t tmp_count = {0};
826 int nbytes = 0; /* the number of send */
827 int total_send = 0; /* the total number of transmit */
828 int num_tag = 0; /* the tag of parameter "-n" */
829 int interval_tag = 0; /* the tag of parameter "-i" */
830 int interval_time = 10; /* the interval time of "-i" */
831 int tradeoff_tag = 0; /* the tag of parameter "-r" */
832 int i;
833 int data_size, send_time, server_port, pkt_delay, pkt_delay_offset, tos, bw;
834 uint32_t t1, t2, curr_t, t1_ms, last_tick, current_tick, last_sleep, current_sleep;
835 UDP_datagram *udp_h;
836 client_hdr *client_h;
837 int udp_h_id = 0;
838 int offset = IPERF_COMMAND_BUFFER_SIZE / sizeof(char *);
839 char *buffer = (char*) iperf_wrapper_malloc( IPERF_TEST_BUFFER_SIZE );
840 // test data init
841 for ( i = 0; i < IPERF_TEST_BUFFER_SIZE; i++ ) {
842 buffer[i] = (i % 10 + '0');
843 }
844 memset( buffer, 0, IPERF_TEST_BUFFER_SIZE );
845 //Statistics init
846 pkt_count = iperf_reset_count( pkt_count );
847 tmp_count = iperf_reset_count( tmp_count );
848 data_size = 0;
849 send_time = 0;
850 server_port = 0;
851 pkt_delay = 0;
852 pkt_delay_offset = 0;
853 tos = 0;
854 bw = 15728640; /* Change from 2621440 to 15728640 */
855
856 //Handle input parameters
857 if ( g_iperf_is_tradeoff_test_server == 0 ) {
858 Server_IP = (char *) ¶meters[0];
859 for ( i = 1; i < 18; i++ ) {
860 if ( strcmp( (char *) ¶meters[i * offset], "-l" ) == 0 ) {
861 i++;
862 data_size = iperf_format_transform( (char *) ¶meters[i * offset] );
863 LWIP_DEBUGF( IPERF_DEBUG, ("Set datagram size = %d Bytes\n", data_size ));
864 } else if ( strcmp( (char *) ¶meters[i * offset], "-t" ) == 0 ) {
865 i++;
866 send_time = atoi( (char *) ¶meters[i * offset] );
867 LWIP_DEBUGF( IPERF_DEBUG, ("Set send times = %d (secs)\n", atoi( (char *) ¶meters[i * offset] ) ));
868 } else if ( strcmp( (char *) ¶meters[i * offset], "-p" ) == 0 ) {
869 i++;
870 server_port = atoi( (char *) ¶meters[i * offset] );
871 } else if ( strcmp( (char *) ¶meters[i * offset], "-d" ) == 0 ) {
872 i++;
873 pkt_delay = atoi( (char *) ¶meters[i * offset] );
874 LWIP_DEBUGF( IPERF_DEBUG, ("Set packet delay = %d (ms)\n", atoi( (char *) ¶meters[i * offset] ) ));
875 } else if ( strcmp( (char *) ¶meters[i * offset], "-n" ) == 0 ) {
876 i++;
877 total_send = iperf_format_transform( (char *) ¶meters[i * offset] );
878 num_tag = 1;
879 LWIP_DEBUGF( IPERF_DEBUG, ("Set number to transmit = %d Bytes\n", total_send ));
880 } else if ( strcmp( (char *) ¶meters[i * offset], "-S" ) == 0 ) {
881 i++;
882 tos = atoi( (char *) ¶meters[i * offset] );
883 LWIP_DEBUGF( IPERF_DEBUG, ("Set TOS = %d\n", atoi( (char *) ¶meters[i * offset] ) ));
884 } else if ( strcmp( (char *) ¶meters[i * offset], "-b" ) == 0 ) {
885 i++;
886 LWIP_DEBUGF( IPERF_DEBUG, ("Set bandwidth = %s\n", (char *) ¶meters[i * offset] ));
887 bw = iperf_format_transform( (char *) ¶meters[i * offset] );
888 if ( bw > 15728640 || bw <= 0 ) {
889 bw = 15728640; /* Change from 2621440 to 15728640 */
890 LWIP_DEBUGF( IPERF_DEBUG, ("Upper limit of bandwith setting = 60Mbits/sec\n" ));
891 }
892 LWIP_DEBUGF( IPERF_DEBUG, ("bandwidth = %d\n", bw ));
893 } else if ( strcmp( (char *) ¶meters[i * offset], "-i" ) == 0 ) {
894 interval_tag = 1;
895 i++;
896 if((interval_time = atoi((char*) ¶meters[i * offset])) == 0) {
897 interval_time = 10;
898 i--;
899 }
900 LWIP_DEBUGF( IPERF_DEBUG, ( "Set %d seconds between periodic bandwidth reports\n" , interval_time));
901 } else if ( strcmp( (char *) ¶meters[i * offset], "-r" ) == 0 ) {
902 tradeoff_tag = 1;
903 LWIP_DEBUGF( IPERF_DEBUG, ( "Set to tradeoff mode\n" ));
904 }
905 }
906 }
907
908 if ( data_size == 0 ) {
909 data_size = 1460;
910 LWIP_DEBUGF( IPERF_DEBUG, ("Default datagram size = %d Bytes\n", data_size ));
911 }
912
913 if ( bw > 0 ) {
914 pkt_delay = (1000 * data_size) / bw;
915
916 // pkt_dalay add 1ms regularly to reduce the offset
917 pkt_delay_offset = (((1000 * data_size) % bw) * 60 / bw);
918 if ( pkt_delay_offset ) {
919 pkt_delay_offset = 10 / pkt_delay_offset;
920 }
921 }
922
923 if ( send_time == 0 ) {
924 if ( num_tag == 1 ) {
925 send_time = 999999;
926 } else {
927 send_time = 10;
928 LWIP_DEBUGF( IPERF_DEBUG, ("Default send times = %d (secs)\n", send_time ));
929 }
930 }
931
932 // Create a new TCP connection handle
933 if ( (sockfd = lwip_socket( AF_INET, SOCK_DGRAM, 0 )) < 0 ) {
934 LWIP_DEBUGF( IPERF_DEBUG, ("[%s:%d] sockfd = %d\n", __FUNCTION__, __LINE__, sockfd ));
935 if ( parameters ) {
936 iperf_wrapper_free( parameters );
937 }
938 aos_task_exit(0);
939 return;
940 }
941
942 if ( lwip_setsockopt( sockfd, IPPROTO_IP, IP_TOS, &tos, sizeof(tos) ) < 0 ) {
943 LWIP_DEBUGF( IPERF_DEBUG, ("Set TOS: fail!\n" ));
944 }
945
946 // Bind to port and IP
947 memset( &servaddr, 0, sizeof(servaddr) );
948 servaddr.sin_family = AF_INET;
949
950 if ( g_iperf_is_tradeoff_test_server == 0 ) {
951 servaddr.sin_addr.s_addr = inet_addr( Server_IP );
952 } else {
953 servaddr.sin_addr.s_addr = g_iperf_server_addr;
954 }
955 LWIP_DEBUGF( IPERF_DEBUG, ("Server address = %x\n", (unsigned int) servaddr.sin_addr.s_addr ));
956
957 if ( server_port == 0 ) {
958 servaddr.sin_port = htons( IPERF_DEFAULT_PORT );
959 LWIP_DEBUGF( IPERF_DEBUG, ("Default server port = %d\n", IPERF_DEFAULT_PORT ));
960 } else {
961 servaddr.sin_port = htons( server_port );
962 LWIP_DEBUGF( IPERF_DEBUG, ("Set server port = %d\n", server_port ));
963 }
964
965 if ( (lwip_connect( sockfd, (struct sockaddr *) &servaddr, sizeof(servaddr) )) < 0 ) {
966 LWIP_DEBUGF( IPERF_DEBUG, ( "Connect failed\n" ));
967 lwip_close( sockfd );
968 if ( parameters ) {
969 iperf_wrapper_free( parameters );
970 }
971 aos_task_exit(0);
972 return;
973 }
974
975 // Init UDP data header
976 udp_h = (UDP_datagram *) &buffer[0];
977 client_h = (client_hdr *) &buffer[12];
978 if ( tradeoff_tag == 1 ) {
979 client_h->flags = htonl( IPERF_HEADER_VERSION1 );
980 } else {
981 client_h->flags = 0;
982 }
983 client_h->num_threads = htonl( 1 );
984 client_h->port = htonl( IPERF_DEFAULT_PORT );
985 client_h->buffer_len = 0;
986 client_h->win_band = htonl( IPERF_DEFAULT_UDP_RATE );
987 if ( num_tag != 1 ) { // time mode
988 client_h->amount = htonl( ~(long )(send_time * 100) );
989 } else {
990 client_h->amount = htonl( (long )(send_time * 100) );
991 client_h->amount &= htonl( 0x7FFFFFFF );
992 }
993
994 iperf_get_current_time( &t1, &t1_ms );
995 last_tick = t1_ms;
996 last_sleep = 0;
997
998 do {
999 udp_h->id = htonl( udp_h_id );
1000 udp_h->tv_sec = htonl( (last_tick + last_sleep) / 1000 );
1001 udp_h->tv_usec = htonl( last_tick + last_sleep );
1002
1003 udp_h_id++;
1004
1005 nbytes = lwip_send( sockfd, buffer, data_size, 0 );
1006 if (nbytes < 0) {
1007 LWIP_DEBUGF( IPERF_DEBUG, ("Send failed\n" ));
1008 break;
1009 }
1010
1011 pkt_count = iperf_calculate_result( nbytes, pkt_count, 0 );
1012
1013 iperf_get_current_time( &curr_t, ¤t_tick );
1014
1015 if ( (pkt_delay_offset != 0) && ((udp_h_id % pkt_delay_offset) == 0) ) {
1016 current_sleep = pkt_delay - (current_tick - last_tick - last_sleep) + 1;
1017 } else {
1018 current_sleep = pkt_delay - (current_tick - last_tick - last_sleep);
1019 }
1020
1021 if ( (int) current_sleep > 0 ) {
1022 aos_msleep( current_sleep );
1023 } else {
1024 current_sleep = 0;
1025 }
1026
1027 last_tick = current_tick;
1028 last_sleep = current_sleep;
1029
1030 #if defined(IPERF_DEBUG_INTERNAL)
1031 // show the debug info per second
1032 if (((bw == 0) && ((udp_h_id % 5000 == 0))) || (udp_h_id % (bw / nbytes) == 0)) {
1033 DBGPRINT_IPERF(IPERF_DEBUG_SEND, "[%s:%d] nbytes = %d, udp_h_id = %d, pkt_delay = %d, current_tick = %"U32_F", current_sleep = %"U32_F"",
1034 __FUNCTION__, __LINE__, nbytes, udp_h_id, pkt_delay, current_tick, current_sleep);
1035 }
1036 #endif
1037
1038 if ( num_tag == 1 ) {
1039 total_send -= nbytes;
1040 }
1041
1042 //Reach total receive number "-n"
1043 if ( total_send < 0 ) {
1044 LWIP_DEBUGF( IPERF_DEBUG, ("Finish Sending\n" ));
1045 break;
1046 }
1047
1048 if ( interval_tag > 0 ) {
1049 if ( ((int)(current_tick - t1_ms) / (interval_time * 1000)) == interval_tag ) {
1050 aos_cli_printf("Interval: %d - %d sec ", (int) (current_tick - t1_ms) / (interval_time * 1000) * interval_time - interval_time,
1051 (int) (current_tick - t1_ms) / (interval_time * 1000) * interval_time );
1052 iperf_display_report( "UDP Client", interval_time, 0, iperf_diff_count( pkt_count, tmp_count ) );
1053 tmp_count = iperf_copy_count( pkt_count, tmp_count );
1054 interval_tag++;
1055 }
1056 iperf_get_current_time( &curr_t, ¤t_tick );
1057 }
1058 } while ( (int)(current_tick + (uint32_t)pkt_delay - t1_ms)/1000 < send_time );
1059
1060 iperf_get_current_time( &t2, 0 );
1061 iperf_display_report( "[Total]UDP Client", t2 - t1, 0, pkt_count );
1062
1063 // send the last datagram
1064 udp_h_id = (-udp_h_id);
1065 udp_h->id = htonl( udp_h_id );
1066 iperf_get_current_time( &curr_t, 0 );
1067 udp_h->tv_sec = htonl( curr_t );
1068 udp_h->tv_usec = htonl( curr_t * 1000 );
1069
1070 nbytes = lwip_send( sockfd, buffer, data_size, 0 );
1071 if (nbytes < 0) {
1072 LWIP_DEBUGF( IPERF_DEBUG, ("Send failed\n" ));
1073 }
1074
1075 //TODO: receive the report from server side and print out
1076
1077 LWIP_DEBUGF( IPERF_DEBUG, ("UDP Client close socket!\n" ));
1078 lwip_close( sockfd );
1079
1080 // tradeoff testing
1081 if ( tradeoff_tag == 1 ) {
1082 LWIP_DEBUGF( IPERF_DEBUG, ("Tradoff test, start server-side.\n" ));
1083 g_iperf_is_tradeoff_test_client = 1;
1084 iperf_udp_run_server( NULL );
1085 g_iperf_is_tradeoff_test_client = 0;
1086 }
1087
1088 if ( parameters ) {
1089 iperf_wrapper_free( parameters );
1090 }
1091
1092 iperf_wrapper_free( buffer );
1093 // For tradeoff mode, task will be deleted in iperf_udp_run_server
1094 if ( g_iperf_is_tradeoff_test_server == 0 ) {
1095 aos_task_exit(0);
1096 }
1097 return;
1098 }
1099
iperf_calculate_result(int pkt_size,count_t pkt_count,int need_to_convert)1100 count_t iperf_calculate_result( int pkt_size, count_t pkt_count, int need_to_convert )
1101 {
1102 if ( pkt_size > 0 ) {
1103 pkt_count.Bytes += pkt_size;
1104 pkt_count.times++;
1105 }
1106
1107 if ( need_to_convert == 1 ) {
1108 if ( pkt_count.Bytes >= 1024 ) {
1109 pkt_count.KBytes += (pkt_count.Bytes / 1024);
1110 pkt_count.Bytes = pkt_count.Bytes % 1024;
1111 }
1112
1113 if ( pkt_count.KBytes >= 1024 ) {
1114 pkt_count.MBytes += (pkt_count.KBytes / 1024);
1115 pkt_count.KBytes = pkt_count.KBytes % 1024;
1116 }
1117
1118 if ( pkt_count.MBytes >= 1024 ) {
1119 pkt_count.GBytes += (pkt_count.MBytes / 1024);
1120 pkt_count.MBytes = pkt_count.MBytes % 1024;
1121 }
1122 }
1123
1124 return pkt_count;
1125 }
1126
iperf_display_report(char * report_title,unsigned time,unsigned h_ms_time,count_t pkt_count)1127 void iperf_display_report( char *report_title, unsigned time, unsigned h_ms_time, count_t pkt_count )
1128 {
1129 unsigned tmp_time = (time * 10) + h_ms_time;
1130
1131 #if defined(IPERF_DEBUG_ENABLE)
1132 DBGPRINT_IPERF(IPERF_DEBUG_REPORT, "\nTransfer in %d.%d seconds: ", time, h_ms_time);
1133 if (pkt_count.GBytes != 0) {
1134 DBGPRINT_IPERF(IPERF_DEBUG_REPORT, "%d GBytes ", pkt_count.GBytes);
1135 }
1136
1137 if (pkt_count.MBytes != 0) {
1138 DBGPRINT_IPERF(IPERF_DEBUG_REPORT, "%d MBytes ", pkt_count.MBytes);
1139 }
1140
1141 if (pkt_count.KBytes != 0) {
1142 DBGPRINT_IPERF(IPERF_DEBUG_REPORT, "%d KBytes ", pkt_count.KBytes);
1143 }
1144
1145 DBGPRINT_IPERF(IPERF_DEBUG_REPORT, "[%s:%d], time = %d, h_ms_time = %d, GBytes = %d, MBytes = %d, KBytes= %d, Bytes= %d ", __FUNCTION__, __LINE__, time, h_ms_time, pkt_count.GBytes, pkt_count.MBytes, pkt_count.KBytes, pkt_count.Bytes);
1146 #endif
1147
1148 aos_cli_printf("%s Bandwidth: ", report_title );
1149
1150 if ( tmp_time != 0 ) {
1151 //Calculate Bandwidth
1152 pkt_count.Bytes = (((pkt_count.KBytes * 8 * 10) % tmp_time) * 1024 + pkt_count.Bytes * 8 * 10) / tmp_time;
1153 pkt_count.KBytes = (((pkt_count.MBytes * 8 * 10) % tmp_time) * 1024 + pkt_count.KBytes * 8 * 10) / tmp_time;
1154 pkt_count.MBytes = (((pkt_count.GBytes * 8 * 10) % tmp_time) * 1024 + pkt_count.MBytes * 8 * 10) / tmp_time;
1155 pkt_count.GBytes = pkt_count.GBytes * 8 * 10 / tmp_time;
1156 } else {
1157 pkt_count.Bytes = 0;
1158 pkt_count.KBytes = 0;
1159 pkt_count.MBytes = 0;
1160 pkt_count.GBytes = 0;
1161 }
1162
1163 pkt_count = iperf_calculate_result( 0, pkt_count, 1 );
1164
1165 if ( pkt_count.GBytes != 0 ) {
1166 aos_cli_printf("%d Gbits ", pkt_count.GBytes );
1167 }
1168
1169 if ( pkt_count.MBytes != 0 ) {
1170 aos_cli_printf("%d Mbits ", pkt_count.MBytes );
1171 }
1172
1173 if ( pkt_count.KBytes != 0 ) {
1174 aos_cli_printf("%d Kbits ", pkt_count.KBytes );
1175 }
1176 aos_cli_printf("%d bits/sec", pkt_count.Bytes );
1177
1178 #ifdef AOS_NETMGR_WITH_MODERN
1179 #ifdef AOS_NET_WITH_WIFI
1180 int rssi;
1181 wifi_service_get_rssi(&rssi);
1182 aos_cli_printf(" rssi: %d dBm", rssi);
1183 #endif /* AOS_NET_WITH_WIFI */
1184 #endif /* AOS_NETMGR_WITH_MODERN */
1185
1186 aos_cli_printf("\n");
1187 #if defined(IPERF_DEBUG_ENABLE)
1188 DBGPRINT_IPERF(IPERF_DEBUG_REPORT, "Receive times: %d", pkt_count.times);
1189 #endif
1190
1191 }
1192
iperf_reset_count(count_t pkt_count)1193 count_t iperf_reset_count( count_t pkt_count )
1194 {
1195 pkt_count.Bytes = 0;
1196 pkt_count.KBytes = 0;
1197 pkt_count.MBytes = 0;
1198 pkt_count.GBytes = 0;
1199 pkt_count.times = 0;
1200
1201 return pkt_count;
1202 }
1203
iperf_copy_count(count_t pkt_count,count_t tmp_count)1204 count_t iperf_copy_count( count_t pkt_count, count_t tmp_count )
1205 {
1206
1207 tmp_count.Bytes = pkt_count.Bytes;
1208 tmp_count.KBytes = pkt_count.KBytes;
1209 tmp_count.MBytes = pkt_count.MBytes;
1210 tmp_count.GBytes = pkt_count.GBytes;
1211 tmp_count.times = pkt_count.times;
1212
1213 return tmp_count;
1214 }
1215
iperf_diff_count(count_t pkt_count,count_t tmp_count)1216 count_t iperf_diff_count( count_t pkt_count, count_t tmp_count )
1217 {
1218 /* pkt_count > tmp_count */
1219 tmp_count.times = pkt_count.times - tmp_count.times;
1220
1221 if ( pkt_count.Bytes >= tmp_count.Bytes ) {
1222 tmp_count.Bytes = pkt_count.Bytes - tmp_count.Bytes;
1223 } else {
1224 tmp_count.Bytes = pkt_count.Bytes + 1024 - tmp_count.Bytes;
1225 if ( pkt_count.KBytes > 0 ) {
1226 pkt_count.KBytes--;
1227 } else if ( pkt_count.MBytes > 0 ) {
1228 pkt_count.MBytes--;
1229 pkt_count.KBytes = 1023;
1230 } else if ( pkt_count.GBytes > 0 ) {
1231 pkt_count.GBytes--;
1232 pkt_count.MBytes = 1023;
1233 pkt_count.KBytes = 1023;
1234 } else {
1235 LWIP_DEBUGF( IPERF_DEBUG, ("Warning: Diff data is wrong.\n" ));
1236 }
1237 }
1238
1239 if ( pkt_count.KBytes >= tmp_count.KBytes ) {
1240 tmp_count.KBytes = pkt_count.KBytes - tmp_count.KBytes;
1241 } else {
1242 tmp_count.KBytes = pkt_count.KBytes + 1024 - tmp_count.KBytes;
1243 if ( pkt_count.MBytes > 0 ) {
1244 pkt_count.MBytes--;
1245 } else if ( pkt_count.GBytes > 0 ) {
1246 pkt_count.GBytes--;
1247 pkt_count.MBytes = 1023;
1248 } else {
1249 LWIP_DEBUGF( IPERF_DEBUG, ("Warning: Diff data is wrong.\n" ));
1250 }
1251 }
1252
1253 if ( pkt_count.MBytes >= tmp_count.MBytes ) {
1254 tmp_count.MBytes = pkt_count.MBytes - tmp_count.MBytes;
1255 } else {
1256 tmp_count.MBytes = pkt_count.MBytes + 1024 - tmp_count.MBytes;
1257 if ( pkt_count.GBytes > 0 ) {
1258 pkt_count.GBytes--;
1259 } else {
1260 LWIP_DEBUGF( IPERF_DEBUG, ("Warning: Diff data is wrong.\n" ));
1261 }
1262 }
1263
1264 #if defined(IPERF_DEBUG_INTERNAL)
1265 DBGPRINT_IPERF(IPERF_DEBUG_REPORT, "\niperf_diff_count: ret.times = %d, ret.GBytes = %d, ret.MBytes = %d, ret.KBytes = %d, ret.Bytes = %d",
1266 tmp_count.times, tmp_count.GBytes, tmp_count.MBytes, tmp_count.KBytes, tmp_count.Bytes);
1267 #endif
1268
1269 return tmp_count;
1270 }
1271
iperf_get_current_time(uint32_t * s,uint32_t * ms)1272 void iperf_get_current_time( uint32_t *s, uint32_t *ms )
1273 {
1274 uint64_t now = aos_now_ms();
1275 if ( s ) {
1276 *s = (uint32_t)(now/1000);
1277 }
1278
1279 if ( ms ) {
1280 *ms = (uint32_t)(now);
1281 }
1282 }
1283
iperf_set_debug_mode(uint32_t debug)1284 void iperf_set_debug_mode( uint32_t debug )
1285 {
1286 g_iperf_debug_feature = debug;
1287 }
1288
iperf_format_transform(char * param)1289 int iperf_format_transform( char *param )
1290 {
1291 char *temp;
1292 int win_size = 0;
1293 int i;
1294
1295 temp = param;
1296
1297 for ( i = 0; temp[i] != '\0'; i++ ) {
1298 if ( temp[i] == 'k' ) {
1299 temp[i] = '\0';
1300 win_size = (1000 * atoi( temp ));
1301 } else if ( temp[i] == 'm' ) {
1302 temp[i] = '\0';
1303 win_size = (1000 * 1000 * atoi( temp ));
1304 } else if ( temp[i] == 'K' ) {
1305 temp[i] = '\0';
1306 win_size = 1024 * atoi( temp );
1307 } else if ( temp[i] == 'M' ) {
1308 temp[i] = '\0';
1309 win_size = 1024 * 1024 * atoi( temp );
1310 } else {
1311 win_size = atoi( param );
1312 }
1313 }
1314
1315 return win_size;
1316 }
1317
1318