/* * Copyright (C) 2017-2019 Alibaba Group Holding Limited */ #include #include #include #include #include "lwip/opt.h" #include "iperf_wrapper.h" #ifdef AOS_NETMGR_WITH_MODERN #ifdef AOS_NET_WITH_WIFI #include "wifi_service.h" #endif /* AOS_NET_WITH_WIFI */ #endif /* AOS_NETMGR_WITH_MODERN */ #include "lwip/debug.h" #include "lwip/sockets.h" #include "lwip/apps/iperf_task.h" #include "lwip/apps/iperf_debug.h" #include "aos/cli.h" /****************************************************** * Macros ******************************************************/ #define IPERF_DEBUG_INTERNAL #define DBGPRINT_IPERF(FEATURE, ...) do { \ if (g_iperf_debug_feature & FEATURE) { \ LWIP_DEBUGF( IPERF_DEBUG, (__VA_ARGS__)); \ } \ } while(0) /****************************************************** * Constants ******************************************************/ #define MAX_WIN_SIZE (1024*1024) /* Private macro */ #define IPERF_DEFAULT_PORT 5001 //Port to listen #define IPERF_HEADER_VERSION1 0x80000000 #define IPERF_DEFAULT_UDP_RATE (1024 * 1024) #define IPERF_TEST_BUFFER_SIZE (2048) /****************************************************** * Enumerations ******************************************************/ /****************************************************** * Type Definitions ******************************************************/ // Private typedef ------------------------------------------------------------- typedef struct count_s { unsigned Bytes; unsigned KBytes; unsigned MBytes; unsigned GBytes; unsigned times; } count_t; // used to reference the 4 byte ID number we place in UDP datagrams // use int32_t if possible, otherwise a 32 bit bitfield (e.g. on J90) typedef struct UDP_datagram { int32_t id; unsigned int tv_sec; unsigned int tv_usec; } UDP_datagram; /* * The client_hdr structure is sent from clients * to servers to alert them of things that need * to happen. Order must be perserved in all * future releases for backward compatibility. * 1.7 has flags, num_threads, port, and buffer_len */ typedef struct client_hdr { /* * flags is a bitmap for different options * the most significant bits are for determining * which information is available. So 1.7 uses * 0x80000000 and the next time information is added * the 1.7 bit will be set and 0x40000000 will be * set signifying additional information. If no * information bits are set then the header is ignored. * The lowest order diferentiates between dualtest and * tradeoff modes, wheither the speaker needs to start * immediately or after the audience finishes. */ int32_t flags; int32_t num_threads; int32_t port; int32_t buffer_len; int32_t win_band; int32_t amount; } client_hdr; /* * The server_hdr structure facilitates the server * report of jitter and loss on the client side. * It piggy_backs on the existing clear to close * packet. */ typedef struct server_hdr { /* * flags is a bitmap for different options * the most significant bits are for determining * which information is available. So 1.7 uses * 0x80000000 and the next time information is added * the 1.7 bit will be set and 0x40000000 will be * set signifying additional information. If no * information bits are set then the header is ignored. */ int32_t flags; int32_t total_len1; int32_t total_len2; int32_t stop_sec; int32_t stop_usec; int32_t error_cnt; int32_t outorder_cnt; int32_t datagrams; int32_t jitter1; int32_t jitter2; } server_hdr; /****************************************************** * Structures ******************************************************/ /****************************************************** * Function Declarations ******************************************************/ count_t iperf_calculate_result( int pkt_size, count_t pkt_count, int need_to_convert ); void iperf_display_report( char *report_title, unsigned time, unsigned h_ms_time, count_t pkt_count ); count_t iperf_reset_count( count_t pkt_count ); count_t iperf_copy_count( count_t pkt_count, count_t tmp_count ); count_t iperf_diff_count( count_t pkt_count, count_t tmp_count ); int iperf_format_transform( char *param ); /****************************************************** * Variables Definitions ******************************************************/ uint32_t g_iperf_debug_feature = 0; int g_iperf_is_tradeoff_test_client = 0; int g_iperf_is_tradeoff_test_server = 0; uint32_t g_iperf_server_addr = 0; /****************************************************** * Function Definitions ******************************************************/ /* members are in network byte order */ void iperf_udp_run_server( char *parameters[] ) { int sockfd; struct sockaddr_in servaddr; struct sockaddr_in cliaddr; int cli_len; struct ip_mreq group; int server_port; int i; count_t pkt_count = {0}; count_t tmp_count = {0}; int nbytes = 0; /* the number of read */ int total_send = 0; /* the total number of send */ int mcast_tag = 0; /* the tag of parameter "-B" */ int interval_tag = 0; /* the tag of parameter "-i" */ int interval_time = 10; /* the interval time of "-i" */ char *mcast; #if defined(IPERF_DEBUG_ENABLE) int send_bytes = 0; /* the number of send */ int tmp = 0; #endif char *buffer = (char*) iperf_wrapper_malloc( IPERF_TEST_BUFFER_SIZE ); uint32_t t1 = 0; uint32_t t2 = 0; uint32_t curr_t = 0; uint32_t curr_h_ms = 0; uint32_t t2_h_ms = 0; uint32_t t1_h_ms = 0; uint32_t tmp_t = 0; uint32_t tmp_h_ms = 0; uint32_t offset_t1 = 0; uint32_t offset_t2 = 0; uint32_t offset_time = 0; UDP_datagram *udp_h = NULL; client_hdr *client_h = NULL; client_hdr client_h_trans = {0}; struct timeval timeout = {0}; timeout.tv_sec = 20; //set recvive timeout = 20(sec) int is_test_started = 0; int udp_h_id = 0; memset( buffer, 0, IPERF_TEST_BUFFER_SIZE ); //Statistics init pkt_count = iperf_reset_count( pkt_count ); tmp_count = iperf_reset_count( tmp_count ); server_port = 0; t1 = 0; t2 = 0; int offset = IPERF_COMMAND_BUFFER_SIZE / sizeof(char *); //Handle input parameters if ( g_iperf_is_tradeoff_test_client == 0 ) { for ( i = 0; i < 13; i++ ) { if ( strcmp( (char *) ¶meters[i * offset], "-p" ) == 0 ) { i++; server_port = atoi( (char *) ¶meters[i * offset] ); } else if ( strcmp( (char *) ¶meters[i * offset], "-n" ) == 0 ) { i++; total_send = iperf_format_transform( (char *) ¶meters[i * offset] ); LWIP_DEBUGF( IPERF_DEBUG, ("Set number to transmit = %d Bytes\n", total_send )); } else if ( strcmp( (char *) ¶meters[i * offset], "-B" ) == 0 ) { i++; mcast = (char *) ¶meters[i * offset]; mcast_tag = 1; LWIP_DEBUGF( IPERF_DEBUG, ("Join Multicast %s\n", mcast) ); } else if ( strcmp( (char *) ¶meters[i * offset], "-i" ) == 0 ) { interval_tag = 1; i++; if((interval_time = atoi((char*) ¶meters[i * offset])) == 0) { interval_time = 10; i--; } LWIP_DEBUGF( IPERF_DEBUG, ( "Set %d seconds between periodic bandwidth reports\n" , interval_time)); } } } // Create a new UDP connection handle if ( (sockfd = lwip_socket( AF_INET, SOCK_DGRAM, 0 )) < 0 ) { LWIP_DEBUGF( IPERF_DEBUG, ("[%s:%d] sockfd = %d\n", __FUNCTION__, __LINE__, sockfd )); if ( parameters ) { iperf_wrapper_free( parameters ); } aos_task_exit(0); return; } // Bind to port and any IP address memset( &servaddr, 0, sizeof(servaddr) ); servaddr.sin_family = AF_INET; servaddr.sin_addr.s_addr = htonl( INADDR_ANY ); if ( server_port == 0 ) { servaddr.sin_port = htons( IPERF_DEFAULT_PORT ); LWIP_DEBUGF( IPERF_DEBUG, ("Default server port = %d\n", IPERF_DEFAULT_PORT )); } else { servaddr.sin_port = htons( server_port ); LWIP_DEBUGF( IPERF_DEBUG, ("Set server port = %d\n", server_port )); } //Multicast settings if ( mcast_tag == 1 ) { group.imr_multiaddr.s_addr = inet_addr( mcast ); group.imr_interface.s_addr = htonl( INADDR_ANY ); if ( lwip_setsockopt( sockfd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *) &group, sizeof(struct ip_mreq) ) < 0 ) { LWIP_DEBUGF( IPERF_DEBUG, ("Setsockopt failed - multicast settings\n" )); } } if ( (lwip_bind( sockfd, (struct sockaddr *) &servaddr, sizeof(servaddr) )) < 0 ) { LWIP_DEBUGF( IPERF_DEBUG, ("[%s:%d]\n", __FUNCTION__, __LINE__ )); if ( parameters ) { iperf_wrapper_free( parameters ); } lwip_close(sockfd); aos_task_exit(0); return; } socklen_t len = sizeof(timeout); if ( lwip_setsockopt( sockfd, SOL_SOCKET, SO_RCVTIMEO, (char *) &timeout, len ) < 0 ) { LWIP_DEBUGF( IPERF_DEBUG, ("Setsockopt failed - cancel receive timeout\n" )); } cli_len = sizeof(cliaddr); // Wait and check the request do { // Handles request do { iperf_get_current_time( &offset_t1, 0 ); nbytes = lwip_recvfrom( sockfd, buffer, IPERF_TEST_BUFFER_SIZE, 0, (struct sockaddr *) &cliaddr, (socklen_t *) &cli_len ); iperf_get_current_time( &offset_t2, 0 ); //if connected to iperf v2.0.1, there is no end package sent from client side if ( (offset_t2 > (offset_t1 + 2)) && (nbytes <= 0) && (pkt_count.times >= 1) ) { offset_time = offset_t2 - offset_t1; } else if ( offset_time != 0 ) { offset_time = 0; } udp_h = (UDP_datagram *) buffer; udp_h_id = (int) ntohl( udp_h->id ); #if defined(IPERF_DEBUG_INTERNAL) client_h = (client_hdr *)&buffer[12]; client_h_trans.flags = (int32_t)(ntohl(client_h->flags)); client_h_trans.num_threads = (int32_t)(ntohl(client_h->num_threads)); client_h_trans.port = (int32_t)(ntohl(client_h->port)); client_h_trans.buffer_len = (int32_t)(ntohl(client_h->buffer_len)); client_h_trans.win_band = (int32_t)(ntohl(client_h->win_band)); client_h_trans.amount = (int32_t)(ntohl(client_h->amount)); 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\"", sockfd, udp_h_id, ntohl(udp_h->tv_sec), ntohl(udp_h->tv_usec), nbytes); 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, cliaddr.sin_port, cliaddr.sin_addr.s_addr); DBGPRINT_IPERF(IPERF_DEBUG_RECEIVE, "[%s:%d] t1 = %"U32_F", t2 = %"U32_F"", __FUNCTION__, __LINE__, t1, t2); 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" , __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); #endif #if defined(IPERF_DEBUG_ENABLE) if (tmp != nbytes) { DBGPRINT_IPERF(IPERF_DEBUG_RECEIVE, "[%s:%d] nbytes=%d ", __FUNCTION__, __LINE__, nbytes); } else { DBGPRINT_IPERF(IPERF_DEBUG_RECEIVE, "."); } tmp = nbytes; #endif pkt_count = iperf_calculate_result( nbytes, pkt_count, 0 ); if ( pkt_count.times == 1 ) { iperf_get_current_time( &t1, &t1_h_ms ); t1_h_ms = (t1_h_ms / 100) % interval_time; } // Report by second if ( (pkt_count.times >= 1 && interval_tag > 0) ) { iperf_get_current_time( &curr_t, &curr_h_ms ); curr_h_ms = (curr_h_ms / 100) % interval_time; if ( offset_time > 0 ) { curr_t -= offset_time; } if ( curr_h_ms >= t1_h_ms ) { tmp_h_ms = curr_h_ms - t1_h_ms; tmp_t = curr_t - t1; } else { tmp_h_ms = curr_h_ms + interval_time - t1_h_ms; tmp_t = curr_t - t1 - 1; } if ( (((int)(curr_t - t1) / interval_time) == interval_tag) && ((curr_h_ms >= t1_h_ms) || ((curr_t - t1) % 10) >= 1) ) { aos_cli_printf("Interval: %d.0 - %d.0 sec ", (int) (curr_t - t1) / interval_time * interval_time - interval_time, (int) (curr_t - t1) / interval_time * interval_time ); iperf_display_report( "UDP Server", interval_time, 0, iperf_diff_count( pkt_count, tmp_count ) ); tmp_count = iperf_copy_count( pkt_count, tmp_count ); interval_tag++; } else if ( ((udp_h_id < 0) || (nbytes <= 0)) && (((tmp_t) % interval_time) != 0) && (is_test_started == 1) ) { aos_cli_printf("Interval: %d.0 - %d.%d sec ", (int) (curr_t - t1 + 1) / interval_time * interval_time - interval_time, (int) tmp_t, (int) tmp_h_ms ); iperf_display_report( "UDP Server", (tmp_t - ((curr_t - t1 + 1) / interval_time * interval_time - interval_time)), tmp_h_ms, iperf_diff_count( pkt_count, tmp_count ) ); tmp_count = iperf_copy_count( pkt_count, tmp_count ); interval_tag++; } } if ( (is_test_started == 0) && (udp_h_id > 0) && (nbytes > 0) ) { is_test_started = 1; } else if ( ((udp_h_id < 0) || (nbytes <= 0)) && (is_test_started == 1) ) { // the last package int32_t old_flag = 0; // test end, save the current time to "t2" if ( pkt_count.times >= 1 ) { /* sync the time if report by second */ if ( interval_tag > 0 ) { t2 = curr_t; t2_h_ms = curr_h_ms; } else { iperf_get_current_time( &t2, &t2_h_ms ); t2_h_ms = (t2_h_ms / 100) % interval_time; if ( offset_time > 0 ) { t2 -= offset_time; } } } // Calculate time: second if ( t2_h_ms >= t1_h_ms ) { t2_h_ms = t2_h_ms - t1_h_ms; t2 = t2 - t1; } else { t2_h_ms = t2_h_ms + interval_time - t1_h_ms; t2 = t2 - t1 - 1; } // print out result iperf_display_report( "[Total]UDP Server", t2, t2_h_ms, pkt_count ); //TODO: need to send the correct report to client-side, flag = 0 means the report is ignored. if ( udp_h_id < 0 ) { old_flag = client_h_trans.flags; client_h_trans.flags = (int32_t) 0; // send the server report to client-side #if defined(IPERF_DEBUG_ENABLE) send_bytes = #endif lwip_sendto( sockfd, buffer, nbytes, 0, (struct sockaddr *) &cliaddr, cli_len ); client_h_trans.flags = old_flag; } #if defined(IPERF_DEBUG_ENABLE) DBGPRINT_IPERF(IPERF_DEBUG_RECEIVE, "[%s:%d]send_bytes = %d, nbytes = %d,", __FUNCTION__, __LINE__, send_bytes, nbytes); #endif client_h = (client_hdr *) &buffer[12]; client_h_trans.flags = (int32_t) (ntohl( client_h->flags )); // Tradeoff mode if ( IPERF_HEADER_VERSION1 & client_h_trans.flags ) { LWIP_DEBUGF( IPERF_DEBUG, ("Tradeoff mode, client-side start.\n" )); g_iperf_is_tradeoff_test_server = 1; g_iperf_server_addr = cliaddr.sin_addr.s_addr; iperf_udp_run_client( NULL ); g_iperf_is_tradeoff_test_server = 0; } LWIP_DEBUGF( IPERF_DEBUG, ("Data transfer is finished.\n" )); //TODO: send report to other side break; } } while ( nbytes > 0 ); #if defined(IPERF_DEBUG_ENABLE) DBGPRINT_IPERF(IPERF_DEBUG_RECEIVE, "[%s:%d] Interval = %"U32_F".%"U32_F" (secs)", __FUNCTION__, __LINE__, t2, t2_h_ms); //sec. #endif } while ( 0 ); LWIP_DEBUGF( IPERF_DEBUG, (" UDP server close socket!\n" )); lwip_close( sockfd ); LWIP_DEBUGF( IPERF_DEBUG, ("If you want to execute iperf server again, please enter \"iperf -s -u\".\n" )); if ( parameters ) { iperf_wrapper_free( parameters ); } iperf_wrapper_free( buffer ); // For tradeoff mode, task will be deleted in iperf_udp_run_client if ( g_iperf_is_tradeoff_test_client == 0 ) { aos_task_exit(0); return; } } void iperf_tcp_run_server( char *parameters[] ) { int listenfd, connfd; struct sockaddr_in servaddr, cliaddr; socklen_t clilen; int server_port; int i; count_t pkt_count = {0}; count_t tmp_count = {0}; int nbytes = 0; /* the number of read */ int total_rcv = 0; /* the total number of receive */ int num_tag = 0; /* the tag of parameter "-n" */ int interval_tag = 0; /* the tag of parameter "-i" */ int interval_time = 10; /* the interval time of "-i" */ #if defined(IPERF_DEBUG_ENABLE) int tmp = 0; #endif uint32_t t1, t2, curr_t; int offset = IPERF_COMMAND_BUFFER_SIZE / sizeof(char *); char *buffer = (char*) iperf_wrapper_malloc( IPERF_TEST_BUFFER_SIZE ); struct timeval timeout = {0}; timeout.tv_sec = 20; //set recvive timeout = 20(sec) memset( buffer, 0, IPERF_TEST_BUFFER_SIZE ); //Statistics init pkt_count = iperf_reset_count( pkt_count ); tmp_count = iperf_reset_count( tmp_count ); server_port = 0; //Handle input parameters for ( i = 0; i < 9; i++ ) { if ( strcmp( (char *) ¶meters[i * offset], "-p" ) == 0 ) { i++; server_port = atoi( (char *) ¶meters[i * offset] ); } else if ( strcmp( (char *) ¶meters[i * offset], "-n" ) == 0 ) { i++; total_rcv = iperf_format_transform( (char *) ¶meters[i * offset] ); num_tag = 1; LWIP_DEBUGF( IPERF_DEBUG, ("Set number to receive = %d Bytes\n", total_rcv )); } else { if ( strcmp( (char *) ¶meters[i * offset], "-i" ) == 0 ) { interval_tag = 1; i++; if((interval_time = atoi((char*) ¶meters[i * offset])) == 0) { interval_time = 10; i--; } LWIP_DEBUGF( IPERF_DEBUG, ( "Set %d seconds between periodic bandwidth reports\n" , interval_time)); } } } // Create a new TCP connection handle if ( (listenfd = lwip_socket( AF_INET, SOCK_STREAM, 0 )) < 0 ) { LWIP_DEBUGF( IPERF_DEBUG, ("[%s:%d] listenfd = %d\n", __FUNCTION__, __LINE__, listenfd )); if ( parameters ) { iperf_wrapper_free( parameters ); } aos_task_exit(0); return; } do { // Bind to port and any IP address memset( &servaddr, 0, sizeof(servaddr) ); servaddr.sin_family = AF_INET; servaddr.sin_addr.s_addr = htonl( INADDR_ANY ); if ( server_port == 0 ) { servaddr.sin_port = htons( IPERF_DEFAULT_PORT ); LWIP_DEBUGF( IPERF_DEBUG, ("Default server port = %d\n", IPERF_DEFAULT_PORT )); } else { servaddr.sin_port = htons( server_port ); LWIP_DEBUGF( IPERF_DEBUG, ("Set server port = %d\n", server_port )); } if ( (lwip_bind( listenfd, (struct sockaddr *) &servaddr, sizeof(servaddr) )) < 0 ) { LWIP_DEBUGF( IPERF_DEBUG, ("[%s:%d] \n", __FUNCTION__, __LINE__ )); break; } // Put the connection into LISTEN state if ( (lwip_listen( listenfd, 1024 )) < 0 ) { LWIP_DEBUGF( IPERF_DEBUG, ("[%s:%d] \n", __FUNCTION__, __LINE__ )); break; } int buflen = 64240; if ( lwip_setsockopt( listenfd, SOL_SOCKET, SO_RCVBUF, (char *) &buflen, sizeof(buflen) ) < 0 ) { LWIP_DEBUGF( IPERF_DEBUG, ("Setsockopt failed - cancel receive buf len\n" )); } do { if ( server_port != 0 ) { LWIP_DEBUGF( IPERF_DEBUG, ("Listen...(port = %d)\n", server_port )); } else { LWIP_DEBUGF( IPERF_DEBUG, ("Listen...(port = %d)\n", IPERF_DEFAULT_PORT )); } // Block and wait for an incoming connection if ( (connfd = lwip_accept( listenfd, (struct sockaddr *) &cliaddr, &clilen )) != -1 ) { socklen_t len = sizeof(timeout); LWIP_DEBUGF( IPERF_DEBUG, ("[%s:%d] Accept... (sockfd=%d)\n", __FUNCTION__, __LINE__, connfd )); if ( lwip_setsockopt( connfd, SOL_SOCKET, SO_RCVTIMEO, (char *) &timeout, len ) < 0 ) { LWIP_DEBUGF( IPERF_DEBUG, ("Setsockopt failed - cancel receive timeout\n" )); } //Connection do { nbytes = lwip_recv( connfd, buffer, IPERF_TEST_BUFFER_SIZE, 0 ); pkt_count = iperf_calculate_result( nbytes, pkt_count, 0 ); if ( pkt_count.times == 1 ) { iperf_get_current_time( &t1, 0 ); } #if defined(IPERF_DEBUG_ENABLE) if (tmp != nbytes) { DBGPRINT_IPERF(IPERF_DEBUG_RECEIVE, "[%s:%d] nbytes=%d ", __FUNCTION__, __LINE__, nbytes); } else { DBGPRINT_IPERF(IPERF_DEBUG_RECEIVE, "."); } tmp = nbytes; #endif if ( num_tag == 1 ) { total_rcv -= nbytes; } //Reach total receive number "-n" if ( total_rcv < 0 ) { LWIP_DEBUGF( IPERF_DEBUG, ("Finish Receiving\n" )); break; } if ( pkt_count.times >= 1 && interval_tag > 0 ) { iperf_get_current_time( &curr_t, 0 ); if ( ((int)(curr_t - t1) / interval_time) == interval_tag ) { aos_cli_printf("Interval: %d - %d sec ", (int) (curr_t - t1) / interval_time * interval_time - interval_time, (int) (curr_t - t1) / interval_time * interval_time ); iperf_display_report( "TCP Server", interval_time, 0, iperf_diff_count( pkt_count, tmp_count ) ); tmp_count = iperf_copy_count( pkt_count, tmp_count ); interval_tag++; } } } while ( nbytes > 0 ); if ( pkt_count.times >= 1 ) { iperf_get_current_time( &t2, 0 ); } LWIP_DEBUGF( IPERF_DEBUG, ("Close socket!\n" )); //Get report iperf_display_report( "[Total]TCP Server", t2 - t1, 0, pkt_count ); //Statistics init pkt_count = iperf_reset_count( pkt_count ); tmp_count = iperf_reset_count( tmp_count ); if ( interval_tag > 0 ) { interval_tag = 1; } else { interval_tag = 0; } lwip_close( connfd ); } } while ( connfd != -1 && num_tag == 0 ); if ( num_tag == 0 ) { LWIP_DEBUGF( IPERF_DEBUG, ("Close socket!\n" )); iperf_display_report( "[Total]TCP Server ", t2 - t1, 0, pkt_count ); } } while ( 0 ); //Loop just once lwip_close( listenfd ); LWIP_DEBUGF( IPERF_DEBUG, ("If you want to execute iperf server again, please enter \"iperf -s\".\n" )); if ( parameters ) { iperf_wrapper_free( parameters ); } iperf_wrapper_free( buffer ); aos_task_exit(0); return; } void iperf_tcp_run_client( char *parameters[] ) { int sockfd; struct sockaddr_in servaddr; char *Server_IP; count_t pkt_count = {0}; count_t tmp_count = {0}; int nbytes = 0; /* the number of send */ int total_send = 0; /* the total number of transmit */ int num_tag = 0; /* the tag of parameter "-n" */ int interval_tag = 0; /* the tag of parameter "-i" */ int interval_time = 10; /* the interval time of "-i" */ int i; int win_size, send_time, server_port, pkt_delay, tos; uint32_t t1, t2, curr_t; int offset = IPERF_COMMAND_BUFFER_SIZE / sizeof(char *); char *buffer = (char*) iperf_wrapper_malloc( IPERF_TEST_BUFFER_SIZE ); pkt_count = iperf_reset_count( pkt_count ); tmp_count = iperf_reset_count( tmp_count ); win_size = 0; send_time = 0; server_port = 0; pkt_delay = 0; tos = 0; memset( buffer, 0, IPERF_TEST_BUFFER_SIZE ); //Handle input parameters Server_IP = (char *) ¶meters[0]; LWIP_DEBUGF( IPERF_DEBUG, ("Servr IP %s \n", Server_IP )); for ( i = 1; i < 18; i++ ) { if ( strcmp( (char *) ¶meters[i * offset], "-w" ) == 0 ) { i++; win_size = iperf_format_transform( (char *) ¶meters[i * offset] ); if ( win_size > MAX_WIN_SIZE ) { LWIP_DEBUGF( IPERF_DEBUG, ("Win size too big, set to %d \n", MAX_WIN_SIZE )); win_size = MAX_WIN_SIZE; } LWIP_DEBUGF( IPERF_DEBUG, ("Set window size = %d Bytes\n", win_size )); } else if ( strcmp( (char *) ¶meters[i * offset], "-t" ) == 0 ) { i++; send_time = atoi( (char *) ¶meters[i * offset] ); LWIP_DEBUGF( IPERF_DEBUG, ("Set send times = %d (secs)\n", atoi( (char *) ¶meters[i * offset] ) )); } else if ( strcmp( (char *) ¶meters[i * offset], "-p" ) == 0 ) { i++; server_port = atoi( (char *) ¶meters[i * offset] ); } else if ( strcmp( (char *) ¶meters[i * offset], "-d" ) == 0 ) { i++; pkt_delay = atoi( (char *) ¶meters[i * offset] ); LWIP_DEBUGF( IPERF_DEBUG, ("Set packet delay = %d (ms)\n", atoi( (char *) ¶meters[i * offset] ) )); } else if ( strcmp( (char *) ¶meters[i * offset], "-n" ) == 0 ) { i++; total_send = iperf_format_transform( (char *) ¶meters[i * offset] ); num_tag = 1; LWIP_DEBUGF( IPERF_DEBUG, ("Set number to transmit = %d Bytes\n", total_send )); } else if ( strcmp( (char *) ¶meters[i * offset], "-S" ) == 0 ) { i++; tos = atoi( (char *) ¶meters[i * offset] ); LWIP_DEBUGF( IPERF_DEBUG, ("Set TOS = %d\n", atoi( (char *) ¶meters[i * offset] ) )); } else if ( strcmp( (char *) ¶meters[i * offset], "-i" ) == 0 ) { interval_tag = 1; i++; if((interval_time = atoi((char*) ¶meters[i * offset])) == 0) { interval_time = 10; i--; } LWIP_DEBUGF( IPERF_DEBUG, ( "Set %d seconds between periodic bandwidth reports\n" , interval_time)); } } if ( win_size == 0 ) { win_size = 1460; LWIP_DEBUGF( IPERF_DEBUG, ("Default window size = %d Bytes\n", win_size )); } if ( send_time == 0 ) { if ( num_tag == 1 ) { send_time = 999999; } else { send_time = 10; LWIP_DEBUGF( IPERF_DEBUG, ("Default send times = %d (secs)\n", send_time )); } } // Create a new TCP connection handle if ( (sockfd = lwip_socket( AF_INET, SOCK_STREAM, 0 )) < 0 ) { LWIP_DEBUGF( IPERF_DEBUG, ("[%s:%d] sockfd = %d\n", __FUNCTION__, __LINE__, sockfd )); if ( parameters ) { iperf_wrapper_free( parameters ); } aos_task_exit(0); return; } if ( lwip_setsockopt( sockfd, IPPROTO_IP, IP_TOS, &tos, sizeof(tos) ) < 0 ) { LWIP_DEBUGF( IPERF_DEBUG, ("Set TOS: fail!\n" )); } // Bind to port and IP memset( &servaddr, 0, sizeof(servaddr) ); servaddr.sin_family = AF_INET; servaddr.sin_addr.s_addr = inet_addr( Server_IP ); if ( server_port == 0 ) { servaddr.sin_port = htons( IPERF_DEFAULT_PORT ); LWIP_DEBUGF( IPERF_DEBUG, ("Default server port = %d\n", IPERF_DEFAULT_PORT )); } else { servaddr.sin_port = htons( server_port ); LWIP_DEBUGF( IPERF_DEBUG, ("Set server port = %d\n", server_port )); } if ( (lwip_connect( sockfd, (struct sockaddr *) &servaddr, sizeof(servaddr) )) < 0 ) { LWIP_DEBUGF( IPERF_DEBUG, ("Connect failed, sockfd is %d, addr is \"%s\"\n", (int) sockfd, ((struct sockaddr *) &servaddr)->sa_data )); lwip_close( sockfd ); if ( parameters ) { iperf_wrapper_free( parameters ); } aos_task_exit(0); return; } iperf_get_current_time( &t1, 0 ); do { nbytes = lwip_send( sockfd, buffer, win_size, 0 ); if (nbytes < 0) { LWIP_DEBUGF( IPERF_DEBUG, ("Send failed\n" )); break; } pkt_count = iperf_calculate_result( nbytes, pkt_count, 0 ); #if defined(IPERF_DEBUG_ENABLE) DBGPRINT_IPERF(IPERF_DEBUG_SEND, "[%s:%d]nbytes=%d ", __FUNCTION__, __LINE__, nbytes); #endif aos_msleep( pkt_delay ); if ( num_tag == 1 ) { total_send -= nbytes; } //Reach total receive number "-n" if ( total_send < 0 ) { LWIP_DEBUGF( IPERF_DEBUG, ("Finish Sending\n" )); break; } if ( interval_tag > 0 ) { iperf_get_current_time( &curr_t, 0 ); if ( ((int)(curr_t - t1) / interval_time) == interval_tag ) { aos_cli_printf("Interval: %d - %d sec ", (int) (curr_t - t1) / interval_time * interval_time - interval_time, (int) (curr_t - t1) / interval_time * interval_time ); iperf_display_report( "TCP Client", interval_time, 0, iperf_diff_count( pkt_count, tmp_count ) ); tmp_count = iperf_copy_count( pkt_count, tmp_count ); interval_tag++; } } iperf_get_current_time( &curr_t, 0 ); } while ( (int)(curr_t - t1) < send_time ); iperf_get_current_time( &t2, 0 ); lwip_close( sockfd ); LWIP_DEBUGF( IPERF_DEBUG, ("Close socket!\n" )); iperf_wrapper_free( buffer ); iperf_display_report( "[Total]TCP Client", t2 - t1, 0, pkt_count ); if ( parameters ) { iperf_wrapper_free( parameters ); } aos_task_exit(0); return; } void iperf_udp_run_client( char *parameters[] ) { int sockfd; struct sockaddr_in servaddr; char *Server_IP = 0; count_t pkt_count = {0}; count_t tmp_count = {0}; int nbytes = 0; /* the number of send */ int total_send = 0; /* the total number of transmit */ int num_tag = 0; /* the tag of parameter "-n" */ int interval_tag = 0; /* the tag of parameter "-i" */ int interval_time = 10; /* the interval time of "-i" */ int tradeoff_tag = 0; /* the tag of parameter "-r" */ int i; int data_size, send_time, server_port, pkt_delay, pkt_delay_offset, tos, bw; uint32_t t1, t2, curr_t, t1_ms, last_tick, current_tick, last_sleep, current_sleep; UDP_datagram *udp_h; client_hdr *client_h; int udp_h_id = 0; int offset = IPERF_COMMAND_BUFFER_SIZE / sizeof(char *); char *buffer = (char*) iperf_wrapper_malloc( IPERF_TEST_BUFFER_SIZE ); // test data init for ( i = 0; i < IPERF_TEST_BUFFER_SIZE; i++ ) { buffer[i] = (i % 10 + '0'); } memset( buffer, 0, IPERF_TEST_BUFFER_SIZE ); //Statistics init pkt_count = iperf_reset_count( pkt_count ); tmp_count = iperf_reset_count( tmp_count ); data_size = 0; send_time = 0; server_port = 0; pkt_delay = 0; pkt_delay_offset = 0; tos = 0; bw = 15728640; /* Change from 2621440 to 15728640 */ //Handle input parameters if ( g_iperf_is_tradeoff_test_server == 0 ) { Server_IP = (char *) ¶meters[0]; for ( i = 1; i < 18; i++ ) { if ( strcmp( (char *) ¶meters[i * offset], "-l" ) == 0 ) { i++; data_size = iperf_format_transform( (char *) ¶meters[i * offset] ); LWIP_DEBUGF( IPERF_DEBUG, ("Set datagram size = %d Bytes\n", data_size )); } else if ( strcmp( (char *) ¶meters[i * offset], "-t" ) == 0 ) { i++; send_time = atoi( (char *) ¶meters[i * offset] ); LWIP_DEBUGF( IPERF_DEBUG, ("Set send times = %d (secs)\n", atoi( (char *) ¶meters[i * offset] ) )); } else if ( strcmp( (char *) ¶meters[i * offset], "-p" ) == 0 ) { i++; server_port = atoi( (char *) ¶meters[i * offset] ); } else if ( strcmp( (char *) ¶meters[i * offset], "-d" ) == 0 ) { i++; pkt_delay = atoi( (char *) ¶meters[i * offset] ); LWIP_DEBUGF( IPERF_DEBUG, ("Set packet delay = %d (ms)\n", atoi( (char *) ¶meters[i * offset] ) )); } else if ( strcmp( (char *) ¶meters[i * offset], "-n" ) == 0 ) { i++; total_send = iperf_format_transform( (char *) ¶meters[i * offset] ); num_tag = 1; LWIP_DEBUGF( IPERF_DEBUG, ("Set number to transmit = %d Bytes\n", total_send )); } else if ( strcmp( (char *) ¶meters[i * offset], "-S" ) == 0 ) { i++; tos = atoi( (char *) ¶meters[i * offset] ); LWIP_DEBUGF( IPERF_DEBUG, ("Set TOS = %d\n", atoi( (char *) ¶meters[i * offset] ) )); } else if ( strcmp( (char *) ¶meters[i * offset], "-b" ) == 0 ) { i++; LWIP_DEBUGF( IPERF_DEBUG, ("Set bandwidth = %s\n", (char *) ¶meters[i * offset] )); bw = iperf_format_transform( (char *) ¶meters[i * offset] ); if ( bw > 15728640 || bw <= 0 ) { bw = 15728640; /* Change from 2621440 to 15728640 */ LWIP_DEBUGF( IPERF_DEBUG, ("Upper limit of bandwith setting = 60Mbits/sec\n" )); } LWIP_DEBUGF( IPERF_DEBUG, ("bandwidth = %d\n", bw )); } else if ( strcmp( (char *) ¶meters[i * offset], "-i" ) == 0 ) { interval_tag = 1; i++; if((interval_time = atoi((char*) ¶meters[i * offset])) == 0) { interval_time = 10; i--; } LWIP_DEBUGF( IPERF_DEBUG, ( "Set %d seconds between periodic bandwidth reports\n" , interval_time)); } else if ( strcmp( (char *) ¶meters[i * offset], "-r" ) == 0 ) { tradeoff_tag = 1; LWIP_DEBUGF( IPERF_DEBUG, ( "Set to tradeoff mode\n" )); } } } if ( data_size == 0 ) { data_size = 1460; LWIP_DEBUGF( IPERF_DEBUG, ("Default datagram size = %d Bytes\n", data_size )); } if ( bw > 0 ) { pkt_delay = (1000 * data_size) / bw; // pkt_dalay add 1ms regularly to reduce the offset pkt_delay_offset = (((1000 * data_size) % bw) * 60 / bw); if ( pkt_delay_offset ) { pkt_delay_offset = 10 / pkt_delay_offset; } } if ( send_time == 0 ) { if ( num_tag == 1 ) { send_time = 999999; } else { send_time = 10; LWIP_DEBUGF( IPERF_DEBUG, ("Default send times = %d (secs)\n", send_time )); } } // Create a new TCP connection handle if ( (sockfd = lwip_socket( AF_INET, SOCK_DGRAM, 0 )) < 0 ) { LWIP_DEBUGF( IPERF_DEBUG, ("[%s:%d] sockfd = %d\n", __FUNCTION__, __LINE__, sockfd )); if ( parameters ) { iperf_wrapper_free( parameters ); } aos_task_exit(0); return; } if ( lwip_setsockopt( sockfd, IPPROTO_IP, IP_TOS, &tos, sizeof(tos) ) < 0 ) { LWIP_DEBUGF( IPERF_DEBUG, ("Set TOS: fail!\n" )); } // Bind to port and IP memset( &servaddr, 0, sizeof(servaddr) ); servaddr.sin_family = AF_INET; if ( g_iperf_is_tradeoff_test_server == 0 ) { servaddr.sin_addr.s_addr = inet_addr( Server_IP ); } else { servaddr.sin_addr.s_addr = g_iperf_server_addr; } LWIP_DEBUGF( IPERF_DEBUG, ("Server address = %x\n", (unsigned int) servaddr.sin_addr.s_addr )); if ( server_port == 0 ) { servaddr.sin_port = htons( IPERF_DEFAULT_PORT ); LWIP_DEBUGF( IPERF_DEBUG, ("Default server port = %d\n", IPERF_DEFAULT_PORT )); } else { servaddr.sin_port = htons( server_port ); LWIP_DEBUGF( IPERF_DEBUG, ("Set server port = %d\n", server_port )); } if ( (lwip_connect( sockfd, (struct sockaddr *) &servaddr, sizeof(servaddr) )) < 0 ) { LWIP_DEBUGF( IPERF_DEBUG, ( "Connect failed\n" )); lwip_close( sockfd ); if ( parameters ) { iperf_wrapper_free( parameters ); } aos_task_exit(0); return; } // Init UDP data header udp_h = (UDP_datagram *) &buffer[0]; client_h = (client_hdr *) &buffer[12]; if ( tradeoff_tag == 1 ) { client_h->flags = htonl( IPERF_HEADER_VERSION1 ); } else { client_h->flags = 0; } client_h->num_threads = htonl( 1 ); client_h->port = htonl( IPERF_DEFAULT_PORT ); client_h->buffer_len = 0; client_h->win_band = htonl( IPERF_DEFAULT_UDP_RATE ); if ( num_tag != 1 ) { // time mode client_h->amount = htonl( ~(long )(send_time * 100) ); } else { client_h->amount = htonl( (long )(send_time * 100) ); client_h->amount &= htonl( 0x7FFFFFFF ); } iperf_get_current_time( &t1, &t1_ms ); last_tick = t1_ms; last_sleep = 0; do { udp_h->id = htonl( udp_h_id ); udp_h->tv_sec = htonl( (last_tick + last_sleep) / 1000 ); udp_h->tv_usec = htonl( last_tick + last_sleep ); udp_h_id++; nbytes = lwip_send( sockfd, buffer, data_size, 0 ); if (nbytes < 0) { LWIP_DEBUGF( IPERF_DEBUG, ("Send failed\n" )); break; } pkt_count = iperf_calculate_result( nbytes, pkt_count, 0 ); iperf_get_current_time( &curr_t, ¤t_tick ); if ( (pkt_delay_offset != 0) && ((udp_h_id % pkt_delay_offset) == 0) ) { current_sleep = pkt_delay - (current_tick - last_tick - last_sleep) + 1; } else { current_sleep = pkt_delay - (current_tick - last_tick - last_sleep); } if ( (int) current_sleep > 0 ) { aos_msleep( current_sleep ); } else { current_sleep = 0; } last_tick = current_tick; last_sleep = current_sleep; #if defined(IPERF_DEBUG_INTERNAL) // show the debug info per second if (((bw == 0) && ((udp_h_id % 5000 == 0))) || (udp_h_id % (bw / nbytes) == 0)) { DBGPRINT_IPERF(IPERF_DEBUG_SEND, "[%s:%d] nbytes = %d, udp_h_id = %d, pkt_delay = %d, current_tick = %"U32_F", current_sleep = %"U32_F"", __FUNCTION__, __LINE__, nbytes, udp_h_id, pkt_delay, current_tick, current_sleep); } #endif if ( num_tag == 1 ) { total_send -= nbytes; } //Reach total receive number "-n" if ( total_send < 0 ) { LWIP_DEBUGF( IPERF_DEBUG, ("Finish Sending\n" )); break; } if ( interval_tag > 0 ) { if ( ((int)(current_tick - t1_ms) / (interval_time * 1000)) == interval_tag ) { aos_cli_printf("Interval: %d - %d sec ", (int) (current_tick - t1_ms) / (interval_time * 1000) * interval_time - interval_time, (int) (current_tick - t1_ms) / (interval_time * 1000) * interval_time ); iperf_display_report( "UDP Client", interval_time, 0, iperf_diff_count( pkt_count, tmp_count ) ); tmp_count = iperf_copy_count( pkt_count, tmp_count ); interval_tag++; } iperf_get_current_time( &curr_t, ¤t_tick ); } } while ( (int)(current_tick + (uint32_t)pkt_delay - t1_ms)/1000 < send_time ); iperf_get_current_time( &t2, 0 ); iperf_display_report( "[Total]UDP Client", t2 - t1, 0, pkt_count ); // send the last datagram udp_h_id = (-udp_h_id); udp_h->id = htonl( udp_h_id ); iperf_get_current_time( &curr_t, 0 ); udp_h->tv_sec = htonl( curr_t ); udp_h->tv_usec = htonl( curr_t * 1000 ); nbytes = lwip_send( sockfd, buffer, data_size, 0 ); if (nbytes < 0) { LWIP_DEBUGF( IPERF_DEBUG, ("Send failed\n" )); } //TODO: receive the report from server side and print out LWIP_DEBUGF( IPERF_DEBUG, ("UDP Client close socket!\n" )); lwip_close( sockfd ); // tradeoff testing if ( tradeoff_tag == 1 ) { LWIP_DEBUGF( IPERF_DEBUG, ("Tradoff test, start server-side.\n" )); g_iperf_is_tradeoff_test_client = 1; iperf_udp_run_server( NULL ); g_iperf_is_tradeoff_test_client = 0; } if ( parameters ) { iperf_wrapper_free( parameters ); } iperf_wrapper_free( buffer ); // For tradeoff mode, task will be deleted in iperf_udp_run_server if ( g_iperf_is_tradeoff_test_server == 0 ) { aos_task_exit(0); } return; } count_t iperf_calculate_result( int pkt_size, count_t pkt_count, int need_to_convert ) { if ( pkt_size > 0 ) { pkt_count.Bytes += pkt_size; pkt_count.times++; } if ( need_to_convert == 1 ) { if ( pkt_count.Bytes >= 1024 ) { pkt_count.KBytes += (pkt_count.Bytes / 1024); pkt_count.Bytes = pkt_count.Bytes % 1024; } if ( pkt_count.KBytes >= 1024 ) { pkt_count.MBytes += (pkt_count.KBytes / 1024); pkt_count.KBytes = pkt_count.KBytes % 1024; } if ( pkt_count.MBytes >= 1024 ) { pkt_count.GBytes += (pkt_count.MBytes / 1024); pkt_count.MBytes = pkt_count.MBytes % 1024; } } return pkt_count; } void iperf_display_report( char *report_title, unsigned time, unsigned h_ms_time, count_t pkt_count ) { unsigned tmp_time = (time * 10) + h_ms_time; #if defined(IPERF_DEBUG_ENABLE) DBGPRINT_IPERF(IPERF_DEBUG_REPORT, "\nTransfer in %d.%d seconds: ", time, h_ms_time); if (pkt_count.GBytes != 0) { DBGPRINT_IPERF(IPERF_DEBUG_REPORT, "%d GBytes ", pkt_count.GBytes); } if (pkt_count.MBytes != 0) { DBGPRINT_IPERF(IPERF_DEBUG_REPORT, "%d MBytes ", pkt_count.MBytes); } if (pkt_count.KBytes != 0) { DBGPRINT_IPERF(IPERF_DEBUG_REPORT, "%d KBytes ", pkt_count.KBytes); } 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); #endif aos_cli_printf("%s Bandwidth: ", report_title ); if ( tmp_time != 0 ) { //Calculate Bandwidth pkt_count.Bytes = (((pkt_count.KBytes * 8 * 10) % tmp_time) * 1024 + pkt_count.Bytes * 8 * 10) / tmp_time; pkt_count.KBytes = (((pkt_count.MBytes * 8 * 10) % tmp_time) * 1024 + pkt_count.KBytes * 8 * 10) / tmp_time; pkt_count.MBytes = (((pkt_count.GBytes * 8 * 10) % tmp_time) * 1024 + pkt_count.MBytes * 8 * 10) / tmp_time; pkt_count.GBytes = pkt_count.GBytes * 8 * 10 / tmp_time; } else { pkt_count.Bytes = 0; pkt_count.KBytes = 0; pkt_count.MBytes = 0; pkt_count.GBytes = 0; } pkt_count = iperf_calculate_result( 0, pkt_count, 1 ); if ( pkt_count.GBytes != 0 ) { aos_cli_printf("%d Gbits ", pkt_count.GBytes ); } if ( pkt_count.MBytes != 0 ) { aos_cli_printf("%d Mbits ", pkt_count.MBytes ); } if ( pkt_count.KBytes != 0 ) { aos_cli_printf("%d Kbits ", pkt_count.KBytes ); } aos_cli_printf("%d bits/sec", pkt_count.Bytes ); #ifdef AOS_NETMGR_WITH_MODERN #ifdef AOS_NET_WITH_WIFI int rssi; wifi_service_get_rssi(&rssi); aos_cli_printf(" rssi: %d dBm", rssi); #endif /* AOS_NET_WITH_WIFI */ #endif /* AOS_NETMGR_WITH_MODERN */ aos_cli_printf("\n"); #if defined(IPERF_DEBUG_ENABLE) DBGPRINT_IPERF(IPERF_DEBUG_REPORT, "Receive times: %d", pkt_count.times); #endif } count_t iperf_reset_count( count_t pkt_count ) { pkt_count.Bytes = 0; pkt_count.KBytes = 0; pkt_count.MBytes = 0; pkt_count.GBytes = 0; pkt_count.times = 0; return pkt_count; } count_t iperf_copy_count( count_t pkt_count, count_t tmp_count ) { tmp_count.Bytes = pkt_count.Bytes; tmp_count.KBytes = pkt_count.KBytes; tmp_count.MBytes = pkt_count.MBytes; tmp_count.GBytes = pkt_count.GBytes; tmp_count.times = pkt_count.times; return tmp_count; } count_t iperf_diff_count( count_t pkt_count, count_t tmp_count ) { /* pkt_count > tmp_count */ tmp_count.times = pkt_count.times - tmp_count.times; if ( pkt_count.Bytes >= tmp_count.Bytes ) { tmp_count.Bytes = pkt_count.Bytes - tmp_count.Bytes; } else { tmp_count.Bytes = pkt_count.Bytes + 1024 - tmp_count.Bytes; if ( pkt_count.KBytes > 0 ) { pkt_count.KBytes--; } else if ( pkt_count.MBytes > 0 ) { pkt_count.MBytes--; pkt_count.KBytes = 1023; } else if ( pkt_count.GBytes > 0 ) { pkt_count.GBytes--; pkt_count.MBytes = 1023; pkt_count.KBytes = 1023; } else { LWIP_DEBUGF( IPERF_DEBUG, ("Warning: Diff data is wrong.\n" )); } } if ( pkt_count.KBytes >= tmp_count.KBytes ) { tmp_count.KBytes = pkt_count.KBytes - tmp_count.KBytes; } else { tmp_count.KBytes = pkt_count.KBytes + 1024 - tmp_count.KBytes; if ( pkt_count.MBytes > 0 ) { pkt_count.MBytes--; } else if ( pkt_count.GBytes > 0 ) { pkt_count.GBytes--; pkt_count.MBytes = 1023; } else { LWIP_DEBUGF( IPERF_DEBUG, ("Warning: Diff data is wrong.\n" )); } } if ( pkt_count.MBytes >= tmp_count.MBytes ) { tmp_count.MBytes = pkt_count.MBytes - tmp_count.MBytes; } else { tmp_count.MBytes = pkt_count.MBytes + 1024 - tmp_count.MBytes; if ( pkt_count.GBytes > 0 ) { pkt_count.GBytes--; } else { LWIP_DEBUGF( IPERF_DEBUG, ("Warning: Diff data is wrong.\n" )); } } #if defined(IPERF_DEBUG_INTERNAL) DBGPRINT_IPERF(IPERF_DEBUG_REPORT, "\niperf_diff_count: ret.times = %d, ret.GBytes = %d, ret.MBytes = %d, ret.KBytes = %d, ret.Bytes = %d", tmp_count.times, tmp_count.GBytes, tmp_count.MBytes, tmp_count.KBytes, tmp_count.Bytes); #endif return tmp_count; } void iperf_get_current_time( uint32_t *s, uint32_t *ms ) { uint64_t now = aos_now_ms(); if ( s ) { *s = (uint32_t)(now/1000); } if ( ms ) { *ms = (uint32_t)(now); } } void iperf_set_debug_mode( uint32_t debug ) { g_iperf_debug_feature = debug; } int iperf_format_transform( char *param ) { char *temp; int win_size = 0; int i; temp = param; for ( i = 0; temp[i] != '\0'; i++ ) { if ( temp[i] == 'k' ) { temp[i] = '\0'; win_size = (1000 * atoi( temp )); } else if ( temp[i] == 'm' ) { temp[i] = '\0'; win_size = (1000 * 1000 * atoi( temp )); } else if ( temp[i] == 'K' ) { temp[i] = '\0'; win_size = 1024 * atoi( temp ); } else if ( temp[i] == 'M' ) { temp[i] = '\0'; win_size = 1024 * 1024 * atoi( temp ); } else { win_size = atoi( param ); } } return win_size; }