2452 lines
76 KiB
C
2452 lines
76 KiB
C
|
#include <stdio.h>
|
||
|
#include <string.h>
|
||
|
#include "cmsis_os2.h"
|
||
|
#include <stdlib.h>
|
||
|
#include "sys/socket.h"
|
||
|
#include "posix/errno.h"
|
||
|
#include "lwip/inet.h"
|
||
|
#include "iperf_api.h"
|
||
|
#include "iperf_config.h"
|
||
|
#include "debug_trace.h"
|
||
|
#include DEBUG_LOG_HEADER_FILE
|
||
|
|
||
|
#include "psdial.h"
|
||
|
#if (defined CHIP_EC618) || (defined CHIP_EC718) || (defined CHIP_EC716)
|
||
|
#include "slpman.h"
|
||
|
#elif defined CHIP_EC617
|
||
|
#include "slpman_ec617.h"
|
||
|
#endif
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
/***************************************************************************************
|
||
|
* Macros
|
||
|
****************************************************************************************/
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
static NET_ZI_DEF BOOL bIperfCltIsGoingOn = 0;
|
||
|
static NET_ZI_DEF BOOL bIperfSrvIsGoingOn = 0;
|
||
|
static NET_ZI_DEF osThreadId_t iperfCLtTask = NULL;
|
||
|
static NET_ZI_DEF osThreadId_t iperfSrvTask = NULL;
|
||
|
static NET_ZI_DEF BOOL bIperfCltTerminRunning = 0;
|
||
|
static NET_ZI_DEF BOOL bIperfSrvTerminRunning = 0;
|
||
|
static NET_ZI_DEF NmIperfReq pIperfClientReq;
|
||
|
static NET_ZI_DEF NmIperfReq pIperfServerReq;
|
||
|
|
||
|
/***************************************************************************************
|
||
|
* structure
|
||
|
****************************************************************************************/
|
||
|
|
||
|
|
||
|
typedef struct IperfCount_Tag
|
||
|
{
|
||
|
UINT32 Bytes;
|
||
|
UINT32 KBytes;
|
||
|
UINT32 MBytes;
|
||
|
UINT32 GBytes;
|
||
|
UINT32 times;
|
||
|
} IperfCount;
|
||
|
|
||
|
|
||
|
typedef struct IperfUdpDatagram_Tag
|
||
|
{
|
||
|
INT32 pkgId;
|
||
|
UINT32 sec;
|
||
|
UINT32 uSec;
|
||
|
} IperfUdpDatagram;
|
||
|
|
||
|
|
||
|
typedef struct IperfClientHeader_Tag
|
||
|
{
|
||
|
|
||
|
INT32 flags;
|
||
|
INT32 numChannels;
|
||
|
INT32 portClient;
|
||
|
INT32 buffLen;
|
||
|
INT32 band;
|
||
|
INT32 amounts;
|
||
|
} IperfClientHeader;
|
||
|
|
||
|
|
||
|
/****************************************************************************************
|
||
|
* Function Declarations
|
||
|
****************************************************************************************/
|
||
|
|
||
|
IperfCount IperfCalculateResult( INT32 pktSize, IperfCount pktCount, INT32 needToConvert );
|
||
|
IperfCount IperfCalculateAddHeader( INT32 domain, INT32 protocol, IperfCount pktCount );
|
||
|
IperfCount IperfResetCount( IperfCount pktCount );
|
||
|
IperfCount IperfCopyCount( IperfCount pktCount, IperfCount tmpCount );
|
||
|
IperfCount IperfDiffCount( IperfCount pktCount, IperfCount tmpCount );
|
||
|
/******************************************************
|
||
|
* Variables Definitions
|
||
|
******************************************************/
|
||
|
|
||
|
/******************************************************
|
||
|
* utility API
|
||
|
******************************************************/
|
||
|
|
||
|
void IperfGetCurrentTime(UINT32 *s, UINT32 *ms) {
|
||
|
UINT32 currentMs = 0;
|
||
|
|
||
|
if(!s && !ms) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
currentMs = osKernelGetTickCount()/portTICK_PERIOD_MS;
|
||
|
|
||
|
if(s) {
|
||
|
*s = currentMs/1000;
|
||
|
}
|
||
|
|
||
|
if(ms) {
|
||
|
*ms = currentMs;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void IperfmSleep( UINT32 ms ) {
|
||
|
osDelay(ms/portTICK_PERIOD_MS);
|
||
|
}
|
||
|
|
||
|
INT32 IperfSetupUdpServerSocket(INT32 *fd, INT32 serverPort, UINT32 rcvTimeout, ip_addr_t *serverAddr, BOOL bNat)
|
||
|
{
|
||
|
struct sockaddr_in servaddr;
|
||
|
struct sockaddr_in6 servaddr6;
|
||
|
|
||
|
if(!fd)
|
||
|
{
|
||
|
ECOMM_TRACE(UNILOG_TCPIP_APP, IperfSetupUdpServerSocket_1, P_WARNING, 0, "IperfSetupClientSocket input fd point is invalid");
|
||
|
return NM_IPERF_PARAM_ERROR;
|
||
|
}
|
||
|
|
||
|
#if LWIP_SO_SNDRCVTIMEO_NONSTANDARD
|
||
|
UINT32 timeout = rcvTimeout;
|
||
|
#else
|
||
|
struct timeval timeout;
|
||
|
timeout.tv_sec = rcvTimeout;
|
||
|
timeout.tv_usec = 0;
|
||
|
#endif
|
||
|
|
||
|
if(serverAddr && (IP_IS_V4(serverAddr) && !ip_addr_isany(serverAddr)))
|
||
|
{
|
||
|
|
||
|
// Create a new UDP connection handle
|
||
|
if( (*fd = socket( AF_INET, SOCK_DGRAM, 0 )) < 0 )
|
||
|
{
|
||
|
|
||
|
ECOMM_TRACE(UNILOG_TCPIP_APP, IperfSetupUdpServerSocket_2, P_WARNING, 0, "create udp server socket fail");
|
||
|
return NM_IPERF_SOCKET_ERROR;
|
||
|
}
|
||
|
|
||
|
// Bind to port and any IP address
|
||
|
memset( &servaddr, 0, sizeof(servaddr) );
|
||
|
servaddr.sin_family = AF_INET;
|
||
|
|
||
|
if(bNat == FALSE)
|
||
|
{
|
||
|
inet_addr_from_ip4addr(&servaddr.sin_addr, ip_2_ip4(serverAddr));
|
||
|
}
|
||
|
servaddr.sin_port = htons( serverPort );
|
||
|
|
||
|
if( (bind( *fd, (struct sockaddr *) &servaddr, sizeof(servaddr) )) < 0 )
|
||
|
{
|
||
|
ECOMM_TRACE(UNILOG_TCPIP_APP, IperfSetupUdpServerSocket_3, P_WARNING, 0, "udp server socket bind fail");
|
||
|
close(*fd);
|
||
|
return NM_IPERF_SOCKET_ERROR;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
else if(serverAddr && (IP_IS_V6(serverAddr) && !ip_addr_isany(serverAddr)))
|
||
|
{
|
||
|
|
||
|
// Create a new UDP connection handle
|
||
|
if( (*fd = socket( AF_INET6, SOCK_DGRAM, 0 )) < 0 )
|
||
|
{
|
||
|
|
||
|
ECOMM_TRACE(UNILOG_TCPIP_APP, IperfSetupUdpServerSocket_4, P_WARNING, 0, "create udp server socket fail");
|
||
|
return NM_IPERF_SOCKET_ERROR;
|
||
|
}
|
||
|
|
||
|
// Bind to port and IP
|
||
|
memset( &servaddr6, 0, sizeof(servaddr6) );
|
||
|
servaddr6.sin6_family = AF_INET6;
|
||
|
|
||
|
if(bNat == FALSE)
|
||
|
{
|
||
|
inet6_addr_from_ip6addr(&servaddr6.sin6_addr, ip_2_ip6(serverAddr));
|
||
|
}
|
||
|
servaddr6.sin6_port = htons( serverPort );
|
||
|
|
||
|
if( (bind( *fd, (struct sockaddr *) &servaddr6, sizeof(servaddr6) )) < 0 )
|
||
|
{
|
||
|
ECOMM_TRACE(UNILOG_TCPIP_APP, IperfSetupUdpServerSocket_5, P_WARNING, 0, "udp server socket bind fail");
|
||
|
close(*fd);
|
||
|
return NM_IPERF_SOCKET_ERROR;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
|
||
|
// Create a new UDP connection handle
|
||
|
if( (*fd = socket( AF_INET, SOCK_DGRAM, 0 )) < 0 )
|
||
|
{
|
||
|
|
||
|
ECOMM_TRACE(UNILOG_TCPIP_APP, IperfSetupUdpServerSocket_6, P_WARNING, 0, "create udp server socket fail");
|
||
|
return NM_IPERF_SOCKET_ERROR;
|
||
|
}
|
||
|
|
||
|
// Bind to port and any IP address
|
||
|
memset( &servaddr, 0, sizeof(servaddr) );
|
||
|
servaddr.sin_family = AF_INET;
|
||
|
servaddr.sin_port = htons( serverPort );
|
||
|
|
||
|
if( (bind( *fd, (struct sockaddr *) &servaddr, sizeof(servaddr) )) < 0 )
|
||
|
{
|
||
|
ECOMM_TRACE(UNILOG_TCPIP_APP, IperfSetupUdpServerSocket_7, P_WARNING, 0, "udp server socket bind fail");
|
||
|
close(*fd);
|
||
|
return NM_IPERF_SOCKET_ERROR;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
socklen_t len = sizeof(timeout);
|
||
|
if( setsockopt( *fd, SOL_SOCKET, SO_RCVTIMEO, (CHAR *) &timeout, len ) < 0 )
|
||
|
{
|
||
|
ECOMM_TRACE(UNILOG_TCPIP_APP, IperfSetupUdpServerSocket_8, P_WARNING, 0, "Setsockopt failed - cancel receive timeout");
|
||
|
close(*fd);
|
||
|
return NM_IPERF_SOCKET_ERROR;
|
||
|
}
|
||
|
|
||
|
return 0;
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
INT32 IperfSetupTcpServerSocket(INT32 *fd, INT32 serverPort, UINT32 rcvTimeout, ip_addr_t *serverAddr)
|
||
|
{
|
||
|
struct sockaddr_in servaddr;
|
||
|
struct sockaddr_in6 servaddr6;
|
||
|
|
||
|
if(!fd)
|
||
|
{
|
||
|
ECOMM_TRACE(UNILOG_TCPIP_APP, IperfSetupTcpServerSocket_1, P_WARNING, 0, "IperfSetupTcpServerSocket input fd point is invalid");
|
||
|
return NM_IPERF_PARAM_ERROR;
|
||
|
}
|
||
|
|
||
|
#if LWIP_SO_SNDRCVTIMEO_NONSTANDARD
|
||
|
UINT32 timeout = rcvTimeout;
|
||
|
#else
|
||
|
struct timeval timeout;
|
||
|
timeout.tv_sec = rcvTimeout;
|
||
|
timeout.tv_usec = 0;
|
||
|
#endif
|
||
|
|
||
|
if(serverAddr && (IP_IS_V4(serverAddr) && !ip_addr_isany(serverAddr)))
|
||
|
{
|
||
|
|
||
|
// Create a new TCP connection handle
|
||
|
if( (*fd = socket( AF_INET, SOCK_STREAM, 0 )) < 0 )
|
||
|
{
|
||
|
|
||
|
ECOMM_TRACE(UNILOG_TCPIP_APP, IperfSetupTcpServerSocket_3, P_WARNING, 0, "create tcp server socket fail");
|
||
|
return NM_IPERF_SOCKET_ERROR;
|
||
|
}
|
||
|
|
||
|
// Bind to port and any IP address
|
||
|
memset( &servaddr, 0, sizeof(servaddr) );
|
||
|
servaddr.sin_family = AF_INET;
|
||
|
inet_addr_from_ip4addr(&servaddr.sin_addr, ip_2_ip4(serverAddr));
|
||
|
servaddr.sin_port = htons( serverPort );
|
||
|
|
||
|
if( (bind( *fd, (struct sockaddr *) &servaddr, sizeof(servaddr) )) < 0 )
|
||
|
{
|
||
|
ECOMM_TRACE(UNILOG_TCPIP_APP, IperfSetupTcpServerSocket_4, P_WARNING, 0, "tcp server socket bind fail");
|
||
|
close(*fd);
|
||
|
return NM_IPERF_SOCKET_ERROR;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
else if(serverAddr && (IP_IS_V6(serverAddr) && !ip_addr_isany(serverAddr)))
|
||
|
{
|
||
|
|
||
|
// Create a new TCP connection handle
|
||
|
if( (*fd = socket( AF_INET6, SOCK_STREAM, 0 )) < 0 )
|
||
|
{
|
||
|
|
||
|
ECOMM_TRACE(UNILOG_TCPIP_APP, IperfSetupTcpServerSocket_5, P_WARNING, 0, "create tcp server socket fail");
|
||
|
return NM_IPERF_SOCKET_ERROR;
|
||
|
}
|
||
|
|
||
|
// Bind to port and IP
|
||
|
memset( &servaddr6, 0, sizeof(servaddr6) );
|
||
|
servaddr6.sin6_family = AF_INET6;
|
||
|
inet6_addr_from_ip6addr(&servaddr6.sin6_addr, ip_2_ip6(serverAddr));
|
||
|
servaddr6.sin6_port = htons( serverPort );
|
||
|
|
||
|
if( (bind( *fd, (struct sockaddr *) &servaddr6, sizeof(servaddr6) )) < 0 )
|
||
|
{
|
||
|
ECOMM_TRACE(UNILOG_TCPIP_APP, IperfSetupTcpServerSocket_6, P_WARNING, 0, "tcp server socket bind fail");
|
||
|
close(*fd);
|
||
|
return NM_IPERF_SOCKET_ERROR;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
|
||
|
// Create a new TCP connection handle
|
||
|
if( (*fd = socket( AF_INET, SOCK_STREAM, 0 )) < 0 )
|
||
|
{
|
||
|
|
||
|
ECOMM_TRACE(UNILOG_TCPIP_APP, IperfSetupTcpServerSocket_7, P_WARNING, 0, "create tcp server socket fail");
|
||
|
return NM_IPERF_SOCKET_ERROR;
|
||
|
}
|
||
|
|
||
|
// Bind to port and any IP address
|
||
|
memset( &servaddr, 0, sizeof(servaddr) );
|
||
|
servaddr.sin_family = AF_INET;
|
||
|
servaddr.sin_port = htons( serverPort );
|
||
|
|
||
|
if( (bind( *fd, (struct sockaddr *) &servaddr, sizeof(servaddr) )) < 0 )
|
||
|
{
|
||
|
ECOMM_TRACE(UNILOG_TCPIP_APP, IperfSetupUdpServerSocket_7, P_WARNING, 0, "udp server socket bind fail");
|
||
|
close(*fd);
|
||
|
return NM_IPERF_SOCKET_ERROR;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
socklen_t len = sizeof(timeout);
|
||
|
if( setsockopt( *fd, SOL_SOCKET, SO_RCVTIMEO, (CHAR *) &timeout, len ) < 0 )
|
||
|
{
|
||
|
ECOMM_TRACE(UNILOG_TCPIP_APP, IperfSetupTcpServerSocket_8, P_WARNING, 0, "Setsockopt failed - cancel receive timeout");
|
||
|
close(*fd);
|
||
|
return NM_IPERF_SOCKET_ERROR;
|
||
|
}
|
||
|
|
||
|
// Put the connection into LISTEN state
|
||
|
if( (listen( *fd, IPERF_SERVER_MAX_LISTEN_NUM )) < 0 )
|
||
|
{
|
||
|
ECOMM_TRACE(UNILOG_TCPIP_APP, IperfSetupTcpServerSocket_9, P_WARNING, 0, "iperf tcp server socket listen fail");
|
||
|
close(*fd);
|
||
|
return NM_IPERF_SOCKET_ERROR;
|
||
|
}
|
||
|
|
||
|
return 0;
|
||
|
|
||
|
|
||
|
}
|
||
|
|
||
|
INT32 IperfSetupClientSocket(INT32 *fd, INT32 protocol, INT32 destPort, ip_addr_t *destAddr)
|
||
|
{
|
||
|
|
||
|
if(!fd)
|
||
|
{
|
||
|
ECOMM_TRACE(UNILOG_TCPIP_APP, IperfSetupClientSocket_1, P_WARNING, 0, "IperfSetupClientSocket input fd point is invalid");
|
||
|
return NM_IPERF_PARAM_ERROR;
|
||
|
}
|
||
|
|
||
|
if(destAddr && (IP_IS_V4(destAddr) && !ip_addr_isany(destAddr)))
|
||
|
{
|
||
|
struct sockaddr_in servaddr;
|
||
|
|
||
|
// Create a new socket
|
||
|
if(protocol == IPERF_STREAM_PROTOCOL_TCP)
|
||
|
{
|
||
|
if( (*fd = socket( AF_INET, SOCK_STREAM, 0 )) < 0 )
|
||
|
{
|
||
|
ECOMM_TRACE(UNILOG_TCPIP_APP, IperfSetupClientSocket_2, P_WARNING, 0, "iperf tcp client create ipv4 tcp socket fail");
|
||
|
return NM_IPERF_SOCKET_ERROR;
|
||
|
}
|
||
|
}
|
||
|
else if(protocol == IPERF_STREAM_PROTOCOL_UDP)
|
||
|
{
|
||
|
if( (*fd = socket( AF_INET, SOCK_DGRAM, 0 )) < 0 )
|
||
|
{
|
||
|
ECOMM_TRACE(UNILOG_TCPIP_APP, IperfSetupClientSocket_3, P_WARNING, 0, "iperf tcp client create ipv4 udp socket fail");
|
||
|
return NM_IPERF_SOCKET_ERROR;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
ECOMM_TRACE(UNILOG_TCPIP_APP, IperfSetupClientSocket_4, P_WARNING, 0, "IperfSetupClientSocket paramter invalid");
|
||
|
return NM_IPERF_PARAM_ERROR;
|
||
|
}
|
||
|
|
||
|
// Bind to port and IP
|
||
|
memset( &servaddr, 0, sizeof(servaddr) );
|
||
|
servaddr.sin_family = AF_INET;
|
||
|
inet_addr_from_ip4addr(&servaddr.sin_addr, ip_2_ip4(destAddr));
|
||
|
servaddr.sin_port = htons( destPort );
|
||
|
|
||
|
if( (connect( *fd, (struct sockaddr *) &servaddr, sizeof(servaddr) )) < 0 )
|
||
|
{
|
||
|
ECOMM_TRACE(UNILOG_TCPIP_APP, IperfSetupClientSocket_5, P_WARNING, 0, "iperf tcp client socket connect fail");
|
||
|
close(*fd);
|
||
|
return NM_IPERF_SOCKET_ERROR;
|
||
|
}
|
||
|
|
||
|
}//ipv6 addr case
|
||
|
else if(destAddr && (IP_IS_V6(destAddr) && !ip_addr_isany(destAddr)))
|
||
|
{
|
||
|
struct sockaddr_in6 servaddr6;
|
||
|
|
||
|
// Create a new socket
|
||
|
if(protocol == IPERF_STREAM_PROTOCOL_TCP)
|
||
|
{
|
||
|
if( (*fd = socket( AF_INET6, SOCK_STREAM, 0 )) < 0 )
|
||
|
{
|
||
|
ECOMM_TRACE(UNILOG_TCPIP_APP, IperfSetupClientSocket_6, P_WARNING, 0, "iperf tcp client create ipv6 tcp socket fail");
|
||
|
return NM_IPERF_SOCKET_ERROR;
|
||
|
|
||
|
}
|
||
|
}
|
||
|
else if(protocol == IPERF_STREAM_PROTOCOL_UDP)
|
||
|
{
|
||
|
if( (*fd = socket( AF_INET6, SOCK_DGRAM, 0 )) < 0 )
|
||
|
{
|
||
|
ECOMM_TRACE(UNILOG_TCPIP_APP, IperfSetupClientSocket_7, P_WARNING, 0, "iperf tcp client create ipv6 udp socket fail");
|
||
|
return NM_IPERF_SOCKET_ERROR;
|
||
|
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
ECOMM_TRACE(UNILOG_TCPIP_APP, IperfSetupClientSocket_8, P_WARNING, 0, "IperfSetupClientSocket paramter invalid");
|
||
|
return NM_IPERF_PARAM_ERROR;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
// Bind to port and IP
|
||
|
memset( &servaddr6, 0, sizeof(servaddr6) );
|
||
|
servaddr6.sin6_family = AF_INET6;
|
||
|
inet6_addr_from_ip6addr(&servaddr6.sin6_addr, ip_2_ip6(destAddr));
|
||
|
servaddr6.sin6_port = htons( destPort );
|
||
|
|
||
|
if( (connect( *fd, (struct sockaddr *) &servaddr6, sizeof(servaddr6) )) < 0 )
|
||
|
{
|
||
|
ECOMM_TRACE(UNILOG_TCPIP_APP, IperfSetupClientSocket_9, P_WARNING, 0, "iperf tcp client socket connect fail");
|
||
|
close(*fd);
|
||
|
return NM_IPERF_SOCKET_ERROR;
|
||
|
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
ECOMM_TRACE(UNILOG_TCPIP_APP, IperfSetupClientSocket_10, P_WARNING, 0, "IperfSetupClientSocket paramter invalid");
|
||
|
return NM_IPERF_PARAM_ERROR;
|
||
|
}
|
||
|
|
||
|
return 0;
|
||
|
|
||
|
|
||
|
}
|
||
|
|
||
|
INT32 IperfNatServerSendUdpPkg(INT32 sockfd, INT32 destPort, ip_addr_t *destAddr)
|
||
|
{
|
||
|
struct sockaddr_in cliaddr; //16 bytes
|
||
|
INT32 cliLen;
|
||
|
IperfUdpDatagram *udpHdr;
|
||
|
IperfClientHeader *clientHdr;
|
||
|
CHAR pBuf[IPERF_UDP_NAT_SERVER_SEND_PKT_LEN];
|
||
|
INT32 ret = -1;
|
||
|
|
||
|
OsaCheck(destAddr != NULL && sockfd >= 0, sockfd, destPort, destAddr);
|
||
|
|
||
|
if(!IP_IS_V4(destAddr) || ip_addr_isany(destAddr))
|
||
|
{
|
||
|
ECOMM_TRACE(UNILOG_TCPIP_APP, IperfNatServerSendUdpPkg_1, P_WARNING, 0,
|
||
|
"IperfNatServerSendUdpPkg dst addr invalid");
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
|
||
|
memset(pBuf, 0x00, IPERF_UDP_NAT_SERVER_SEND_PKT_LEN);
|
||
|
|
||
|
cliLen = sizeof(cliaddr);
|
||
|
|
||
|
memset(&cliaddr, 0, sizeof(cliaddr) );
|
||
|
cliaddr.sin_family = AF_INET;
|
||
|
|
||
|
if (destPort == 0 )
|
||
|
{
|
||
|
destPort = IPERF_DEFAULT_PORT;
|
||
|
}
|
||
|
|
||
|
cliaddr.sin_port = htons(destPort);
|
||
|
|
||
|
ECOMM_TRACE(UNILOG_TCPIP_APP, IperfNatServerSendUdpPkg_2, P_INFO, 1,
|
||
|
"Iperf, send one UDP pkg to dest port: %d", destPort);
|
||
|
|
||
|
inet_addr_from_ip4addr(&cliaddr.sin_addr, ip_2_ip4(destAddr));
|
||
|
|
||
|
// Init UDP data header
|
||
|
udpHdr = (IperfUdpDatagram *)&pBuf[0]; //12 bytes
|
||
|
udpHdr->pkgId = 0; //htonl(udpHdrId);
|
||
|
udpHdr->sec = htonl(200);
|
||
|
udpHdr->uSec = htonl(0);
|
||
|
clientHdr = (IperfClientHeader *) &pBuf[12]; //24bytes
|
||
|
clientHdr->flags = 0;
|
||
|
clientHdr->numChannels = htonl(1);
|
||
|
clientHdr->portClient = htonl(destPort);
|
||
|
clientHdr->buffLen = 0;
|
||
|
clientHdr->band = htonl(22000);
|
||
|
clientHdr->amounts = htonl( ~(long )(1000 * 100));
|
||
|
|
||
|
ret = sendto(sockfd, pBuf, IPERF_UDP_NAT_SERVER_SEND_PKT_LEN, 0, (struct sockaddr *)&cliaddr, cliLen);
|
||
|
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
/******************************************************
|
||
|
* Function Definitions
|
||
|
******************************************************/
|
||
|
/* members are in network byte order */
|
||
|
void IperfUdpRunNatServer( void* arg )
|
||
|
{
|
||
|
|
||
|
NmIperfReq * serverParam = (NmIperfReq *)arg;
|
||
|
INT32 sockfd;
|
||
|
struct sockaddr_in cliaddr;
|
||
|
INT32 cliLen;
|
||
|
IperfCount pktCount = {0, 0, 0, 0, 0};
|
||
|
IperfCount tmpCount = {0, 0, 0, 0, 0};
|
||
|
INT32 nBytes = 0;
|
||
|
UINT32 intervalTag;
|
||
|
INT32 serverPort = 0;
|
||
|
UINT16 rcvTime;
|
||
|
UINT32 totalRptNum = 1;
|
||
|
UINT32 tmpRptNum = 0;
|
||
|
UINT32 rcvTimeout;
|
||
|
INT32 ret;
|
||
|
|
||
|
slpManRet_t pmuRet = RET_UNKNOW_FALSE;
|
||
|
UINT8 iperfPmuHdr = 0;
|
||
|
|
||
|
UINT32 t1,t1_ms,t2,t2_ms, currTime, offsetTime1;
|
||
|
IperfUdpDatagram *udpHdr;
|
||
|
IperfClientHeader *clientHdr;
|
||
|
IperfClientHeader clientHdrTrans;
|
||
|
|
||
|
INT32 isTestStarted = 0;
|
||
|
INT32 udpHdrId = 0;
|
||
|
|
||
|
struct NmAtiIperfResultIndTag nmIperfResult;
|
||
|
memset(&nmIperfResult, 0, sizeof(struct NmAtiIperfResultIndTag));
|
||
|
|
||
|
//init setting
|
||
|
if(serverParam->rptIntervalPresent && serverParam->rptIntervalS > 0)
|
||
|
{
|
||
|
intervalTag = serverParam->rptIntervalS;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
intervalTag = IPERF_DEFAULT_REPORT_INTERVAL;
|
||
|
}
|
||
|
|
||
|
if(serverParam->durationPresent && serverParam->durationS > 0)
|
||
|
{
|
||
|
rcvTime = serverParam->durationS;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
rcvTime = IPERF_MAX_SEND_RCV_TIME;
|
||
|
}
|
||
|
|
||
|
if(serverParam->port > 0)
|
||
|
{
|
||
|
serverPort = serverParam->port;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
serverPort = IPERF_DEFAULT_PORT;
|
||
|
}
|
||
|
|
||
|
if (intervalTag < IPERF_SERVER_RECEIVE_TIMEOUT)
|
||
|
{
|
||
|
rcvTimeout = intervalTag;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
rcvTimeout = IPERF_SERVER_RECEIVE_TIMEOUT;
|
||
|
}
|
||
|
|
||
|
ECOMM_TRACE(UNILOG_TCPIP_APP, IperfUdpRunNatServer_1, P_SIG, 0, "iperf udp nat server task start runing");
|
||
|
|
||
|
//alloc rcv buffer
|
||
|
CHAR *buffer = (CHAR*) mallocEc( IPERF_TEST_BUFFER_SIZE );
|
||
|
if(!buffer)
|
||
|
{
|
||
|
ECOMM_TRACE(UNILOG_TCPIP_APP, IperfUdpRunNatServer_2, P_WARNING, 0, "malloc buffer fail");
|
||
|
nmIperfResult.mode = NM_IPERF_MODE_SERVER;
|
||
|
nmIperfResult.result = NM_IPERF_MALLOC_ERROR;
|
||
|
AppMgrSendIperfResultInd(&nmIperfResult, serverParam->reqHandle);
|
||
|
|
||
|
iperfSrvTask = NULL;
|
||
|
bIperfSrvIsGoingOn = 0;
|
||
|
osThreadExit();
|
||
|
}
|
||
|
memset(buffer, 0 ,IPERF_TEST_BUFFER_SIZE);
|
||
|
|
||
|
//setup udp nat server socket
|
||
|
ret = IperfSetupUdpServerSocket(&sockfd, serverPort, rcvTimeout, &serverParam->destAddr, TRUE);
|
||
|
if (ret != 0)
|
||
|
{
|
||
|
ECOMM_TRACE(UNILOG_TCPIP_APP, IperfUdpRunNatServer_3, P_WARNING, 0, "setup udp nat server socket fail");
|
||
|
nmIperfResult.mode = NM_IPERF_MODE_SERVER;
|
||
|
nmIperfResult.result = ret;
|
||
|
AppMgrSendIperfResultInd(&nmIperfResult, serverParam->reqHandle);
|
||
|
|
||
|
iperfSrvTask = NULL;
|
||
|
bIperfSrvIsGoingOn = 0;
|
||
|
freeEc(buffer);
|
||
|
osThreadExit();
|
||
|
}
|
||
|
|
||
|
cliLen = sizeof(cliaddr);
|
||
|
|
||
|
/*
|
||
|
* start iperf, iperf task don't allow to enter HIB/Sleep2 state before iperf terminated
|
||
|
*/
|
||
|
pmuRet = slpManApplyPlatVoteHandle("iperfserver", &iperfPmuHdr);
|
||
|
OsaCheck(pmuRet == RET_TRUE, pmuRet, 0, 0);
|
||
|
|
||
|
pmuRet = slpManPlatVoteDisableSleep(iperfPmuHdr, SLP_SLP2_STATE);
|
||
|
OsaCheck(pmuRet == RET_TRUE, pmuRet, 0, 0);
|
||
|
|
||
|
//fisrt send one UL pkg for NAT server
|
||
|
if(IperfNatServerSendUdpPkg(sockfd, serverPort, &serverParam->destAddr) < 0)
|
||
|
{
|
||
|
ECOMM_TRACE(UNILOG_TCPIP_APP, IperfUdpRunNatServer_11, P_WARNING, 0, "send one packet to client for NAT case fail");
|
||
|
}
|
||
|
|
||
|
IperfGetCurrentTime( &offsetTime1, 0 );
|
||
|
|
||
|
// Wait and check the request
|
||
|
do {
|
||
|
// Handles request
|
||
|
do {
|
||
|
|
||
|
//check cfun status first
|
||
|
if(!psDailBeCfun1State())
|
||
|
{
|
||
|
ECOMM_TRACE(UNILOG_TCPIP_APP, IperfUdpRunNatServer_4, P_WARNING, 0, "Not CFUN1, iperf will terminal");
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
nBytes = recvfrom(sockfd, buffer, IPERF_TEST_BUFFER_SIZE, 0, (struct sockaddr *) &cliaddr, (socklen_t *) &cliLen );
|
||
|
|
||
|
|
||
|
udpHdr = (IperfUdpDatagram *) buffer;
|
||
|
udpHdrId = (INT32) ntohl( udpHdr->pkgId );
|
||
|
|
||
|
pktCount = IperfCalculateResult( nBytes, pktCount, 0 );
|
||
|
|
||
|
if(nBytes > 0)
|
||
|
{
|
||
|
if(IP_IS_V4(&serverParam->destAddr))
|
||
|
{
|
||
|
pktCount = IperfCalculateAddHeader(IPERF_STREAM_DOMAIN_IP4, IPERF_STREAM_PROTOCOL_UDP, pktCount);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
pktCount = IperfCalculateAddHeader(IPERF_STREAM_DOMAIN_IP6, IPERF_STREAM_PROTOCOL_UDP, pktCount);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//record the time when rcv the first packet
|
||
|
if( pktCount.times == 1 )
|
||
|
{
|
||
|
IperfGetCurrentTime( &t1, &t1_ms);
|
||
|
}
|
||
|
|
||
|
IperfGetCurrentTime( &currTime, 0 );
|
||
|
|
||
|
// Report every interval time
|
||
|
if( intervalTag > 0 )
|
||
|
{
|
||
|
if( currTime - offsetTime1 > 0 )
|
||
|
{
|
||
|
tmpRptNum = (((int)(currTime - offsetTime1)) / intervalTag);
|
||
|
if(tmpRptNum > 0)
|
||
|
{
|
||
|
if( tmpRptNum == totalRptNum)
|
||
|
{
|
||
|
|
||
|
nmIperfResult.mode = NM_IPERF_MODE_SERVER;
|
||
|
nmIperfResult.result = NM_IPERF_ONE_REPORT_SUCCESS;
|
||
|
nmIperfResult.dataNum = pktCount.Bytes - tmpCount.Bytes;
|
||
|
nmIperfResult.bandwidth = (((pktCount.Bytes - tmpCount.Bytes) * 8)/intervalTag);
|
||
|
|
||
|
ECOMM_TRACE(UNILOG_TCPIP_APP, IperfUdpRunNatServer_report_1, P_SIG, 2, "iperf UDP nat server report,send %u bytes payload packet, bandwidth %u bps", nmIperfResult.dataNum, nmIperfResult.bandwidth);
|
||
|
|
||
|
AppMgrSendIperfResultInd(&nmIperfResult, serverParam->reqHandle);
|
||
|
|
||
|
tmpCount = IperfCopyCount( pktCount, tmpCount );
|
||
|
|
||
|
totalRptNum = tmpRptNum + 1;
|
||
|
}
|
||
|
else if(tmpRptNum > totalRptNum)
|
||
|
{
|
||
|
nmIperfResult.mode = NM_IPERF_MODE_SERVER;
|
||
|
nmIperfResult.result = NM_IPERF_ONE_REPORT_SUCCESS;
|
||
|
nmIperfResult.dataNum = pktCount.Bytes - tmpCount.Bytes;
|
||
|
nmIperfResult.bandwidth = (((pktCount.Bytes - tmpCount.Bytes) * 8)/(intervalTag *(tmpRptNum - totalRptNum + 1)));
|
||
|
|
||
|
ECOMM_TRACE(UNILOG_TCPIP_APP, IperfUdpRunNatServer_report_2, P_SIG, 2, "iperf UDP nat server report,send %u bytes payload packet, bandwidth %u bps", nmIperfResult.dataNum, nmIperfResult.bandwidth);
|
||
|
|
||
|
AppMgrSendIperfResultInd(&nmIperfResult, serverParam->reqHandle);
|
||
|
|
||
|
tmpCount = IperfCopyCount( pktCount, tmpCount );
|
||
|
|
||
|
totalRptNum = tmpRptNum + 1;
|
||
|
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
//rcv the fisrt valid udp packet
|
||
|
if( (isTestStarted == 0) && (udpHdrId > 0) && (nBytes > 0) )
|
||
|
{
|
||
|
isTestStarted = 1;
|
||
|
}//rcv the end udp packet
|
||
|
else if ( (udpHdrId < 0) && (isTestStarted == 1) )
|
||
|
{ // the last package
|
||
|
INT32 oldFlag = 0;
|
||
|
|
||
|
// print out result
|
||
|
//TODO: need to send the correct report to client-side, flag = 0 means the report is ignored.
|
||
|
//if( udpHdrId < 0 )
|
||
|
//{
|
||
|
oldFlag = clientHdrTrans.flags;
|
||
|
clientHdrTrans.flags = (INT32) 0;
|
||
|
|
||
|
// send the server report to client-side
|
||
|
sendto( sockfd, buffer, nBytes, 0, (struct sockaddr *) &cliaddr, cliLen );
|
||
|
clientHdrTrans.flags = oldFlag;
|
||
|
//}
|
||
|
|
||
|
clientHdr = (IperfClientHeader *) &buffer[12];
|
||
|
clientHdrTrans.flags = (INT32) (ntohl( clientHdr->flags ));
|
||
|
|
||
|
// Tradeoff mode
|
||
|
if( IPERF_HEADER_VERSION1 & clientHdrTrans.flags )
|
||
|
{
|
||
|
ECOMM_TRACE(UNILOG_TCPIP_APP, IperfUdpRunNatServer_6, P_WARNING, 0, "Tradeoff mode, client-side not support");
|
||
|
}
|
||
|
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
//send one packet for NAT case,if rcv packet timeout
|
||
|
if(nBytes <= 0 && sock_get_errno(sockfd) == ETIME)
|
||
|
{
|
||
|
if(IperfNatServerSendUdpPkg(sockfd, serverPort, &serverParam->destAddr) < 0)
|
||
|
{
|
||
|
ECOMM_TRACE(UNILOG_TCPIP_APP, IperfUdpRunNatServer_7, P_WARNING, 0, "send one packet to client for NAT case fail");
|
||
|
}
|
||
|
else
|
||
|
{//if send fail,check whether need stop iperf server
|
||
|
if(bIperfSrvTerminRunning || currTime - offsetTime1 > rcvTime)
|
||
|
{
|
||
|
break;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
continue;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//check whether rcv stop command
|
||
|
if(bIperfSrvTerminRunning)
|
||
|
{
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
//check whether the total rcv timer timeout
|
||
|
if((currTime - offsetTime1 > rcvTime) && (currTime > offsetTime1))
|
||
|
{
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
//check whether socket error and is not timeout
|
||
|
if( nBytes <= 0 && sock_get_errno(sockfd) != ETIME)
|
||
|
{
|
||
|
if(sock_get_errno(sockfd) != EHOSTUNREACH)
|
||
|
{
|
||
|
ECOMM_TRACE(UNILOG_TCPIP_APP, IperfUdpRunNatServer_8, P_WARNING, 0, "iperf UDP nat server socket rcv error");
|
||
|
break;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
ECOMM_TRACE(UNILOG_TCPIP_APP, IperfUdpRunNatServer_12, P_INFO, 0, "iperf UDP nat server ,maybe detach, try again");
|
||
|
}
|
||
|
}
|
||
|
}while(TRUE);
|
||
|
|
||
|
}while(FALSE);
|
||
|
|
||
|
// the end report
|
||
|
IperfGetCurrentTime( &t2, &t2_ms );
|
||
|
|
||
|
nmIperfResult.mode = NM_IPERF_MODE_SERVER;
|
||
|
nmIperfResult.result = NM_IPERF_END_REPORT_SUCCESS;
|
||
|
nmIperfResult.dataNum = pktCount.Bytes;
|
||
|
if(pktCount.times > 0)
|
||
|
{
|
||
|
if(t2 > t1)
|
||
|
{
|
||
|
nmIperfResult.bandwidth = ((pktCount.Bytes * 8)/(t2 - t1));
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if(t2_ms > t1_ms)
|
||
|
{
|
||
|
nmIperfResult.bandwidth = ((pktCount.Bytes * 8 * 1000)/(t2_ms - t1_ms));
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
nmIperfResult.bandwidth = 0;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
nmIperfResult.bandwidth = 0;
|
||
|
}
|
||
|
AppMgrSendIperfResultInd(&nmIperfResult, serverParam->reqHandle);
|
||
|
|
||
|
ECOMM_TRACE(UNILOG_TCPIP_APP, IperfUdpRunNatServer_9, P_SIG, 2, "iperf UDP nat server report,TOTAL receive %u bytes payload packet, bandwidth %u bps", nmIperfResult.dataNum, nmIperfResult.bandwidth);
|
||
|
|
||
|
close( sockfd );
|
||
|
freeEc( buffer );
|
||
|
bIperfSrvTerminRunning = 0;
|
||
|
iperfSrvTask = NULL;
|
||
|
bIperfSrvIsGoingOn = 0;
|
||
|
|
||
|
/* before iperf task exit, should allow to enter HIB/Sleep2, and release hander */
|
||
|
pmuRet = slpManPlatVoteEnableSleep(iperfPmuHdr, SLP_SLP2_STATE);
|
||
|
OsaCheck(pmuRet == RET_TRUE, pmuRet, 0, 0);
|
||
|
|
||
|
pmuRet = slpManGivebackPlatVoteHandle(iperfPmuHdr);
|
||
|
OsaCheck(pmuRet == RET_TRUE, pmuRet, 0, 0);
|
||
|
|
||
|
ECOMM_TRACE(UNILOG_TCPIP_APP, IperfUdpRunNatServer_10, P_SIG, 0, "iperf UDP nat server terminal");
|
||
|
|
||
|
osThreadExit();
|
||
|
}
|
||
|
|
||
|
void IperfUdpRunServer( void* arg )
|
||
|
{
|
||
|
|
||
|
NmIperfReq * serverParam = (NmIperfReq *)arg;
|
||
|
INT32 sockfd;
|
||
|
struct sockaddr_in cliaddr;
|
||
|
INT32 cliLen;
|
||
|
IperfCount pktCount = {0, 0, 0, 0, 0};
|
||
|
IperfCount tmpCount = {0, 0, 0, 0, 0};
|
||
|
INT32 nBytes = 0;
|
||
|
INT32 serverPort = 0;
|
||
|
UINT16 rcvTime;
|
||
|
UINT32 totalRptNum = 1;
|
||
|
UINT32 tmpRptNum = 0;
|
||
|
UINT32 intervalTag;
|
||
|
UINT32 rcvTimeout;
|
||
|
INT32 ret;
|
||
|
|
||
|
slpManRet_t pmuRet = RET_UNKNOW_FALSE;
|
||
|
UINT8 iperfPmuHdr = 0;
|
||
|
|
||
|
UINT32 t1,t1_ms,t2,t2_ms, currTime, offsetTime1;
|
||
|
IperfUdpDatagram *udpHdr;
|
||
|
IperfClientHeader *clientHdr;
|
||
|
IperfClientHeader clientHdrTrans;
|
||
|
|
||
|
int isTestStarted = 0;
|
||
|
INT32 udpHdrId = 0;
|
||
|
|
||
|
struct NmAtiIperfResultIndTag nmIperfResult;
|
||
|
memset(&nmIperfResult, 0, sizeof(struct NmAtiIperfResultIndTag));
|
||
|
|
||
|
//init setting
|
||
|
if(serverParam->rptIntervalPresent && serverParam->rptIntervalS > 0)
|
||
|
{
|
||
|
intervalTag = serverParam->rptIntervalS;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
intervalTag = IPERF_DEFAULT_REPORT_INTERVAL;
|
||
|
}
|
||
|
|
||
|
if(serverParam->durationPresent && serverParam->durationS > 0)
|
||
|
{
|
||
|
rcvTime = serverParam->durationS;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
rcvTime = IPERF_MAX_SEND_RCV_TIME;
|
||
|
}
|
||
|
|
||
|
if(serverParam->port > 0)
|
||
|
{
|
||
|
serverPort = serverParam->port;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
serverPort = IPERF_DEFAULT_PORT;
|
||
|
}
|
||
|
|
||
|
if(intervalTag < IPERF_SERVER_RECEIVE_TIMEOUT)
|
||
|
{
|
||
|
rcvTimeout = intervalTag;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
rcvTimeout = IPERF_SERVER_RECEIVE_TIMEOUT;
|
||
|
}
|
||
|
|
||
|
ECOMM_TRACE(UNILOG_TCPIP_APP, IperfUdpRunServer_1, P_SIG, 0, "iperf udp server task start runing");
|
||
|
|
||
|
//init rcv buffer
|
||
|
CHAR *buffer = (CHAR*) mallocEc( IPERF_TEST_BUFFER_SIZE );
|
||
|
if(!buffer)
|
||
|
{
|
||
|
ECOMM_TRACE(UNILOG_TCPIP_APP, IperfUdpRunServer_2, P_WARNING, 0, "malloc buffer fail");
|
||
|
nmIperfResult.mode = NM_IPERF_MODE_SERVER;
|
||
|
nmIperfResult.result = NM_IPERF_MALLOC_ERROR;
|
||
|
AppMgrSendIperfResultInd(&nmIperfResult, serverParam->reqHandle);
|
||
|
|
||
|
iperfSrvTask = NULL;
|
||
|
bIperfSrvIsGoingOn = 0;
|
||
|
osThreadExit();
|
||
|
}
|
||
|
memset(buffer, 0 ,IPERF_TEST_BUFFER_SIZE);
|
||
|
|
||
|
//setup udp server socket
|
||
|
ret = IperfSetupUdpServerSocket(&sockfd, serverPort, rcvTimeout, &serverParam->destAddr, FALSE);
|
||
|
if(ret != 0)
|
||
|
{
|
||
|
ECOMM_TRACE(UNILOG_TCPIP_APP, IperfUdpRunServer_3, P_WARNING, 0, "setup udp server socket fail");
|
||
|
nmIperfResult.mode = NM_IPERF_MODE_SERVER;
|
||
|
nmIperfResult.result = ret;
|
||
|
AppMgrSendIperfResultInd(&nmIperfResult, serverParam->reqHandle);
|
||
|
|
||
|
iperfSrvTask = NULL;
|
||
|
bIperfSrvIsGoingOn = 0;
|
||
|
freeEc(buffer);
|
||
|
osThreadExit();
|
||
|
}
|
||
|
|
||
|
cliLen = sizeof(cliaddr);
|
||
|
|
||
|
/*
|
||
|
* start iperf, iperf task don't allow to enter HIB/Sleep2 state before iperf terminated
|
||
|
*/
|
||
|
pmuRet = slpManApplyPlatVoteHandle("iperfserver", &iperfPmuHdr);
|
||
|
OsaCheck(pmuRet == RET_TRUE, pmuRet, 0, 0);
|
||
|
|
||
|
pmuRet = slpManPlatVoteDisableSleep(iperfPmuHdr, SLP_SLP2_STATE);
|
||
|
OsaCheck(pmuRet == RET_TRUE, pmuRet, 0, 0);
|
||
|
|
||
|
IperfGetCurrentTime( &offsetTime1, 0 );
|
||
|
|
||
|
// Wait and check the request
|
||
|
do {
|
||
|
// Handles request
|
||
|
do {
|
||
|
|
||
|
//check cfun status first
|
||
|
if(!psDailBeCfun1State())
|
||
|
{
|
||
|
ECOMM_TRACE(UNILOG_TCPIP_APP, IperfUdpRunServer_4, P_WARNING, 0, "Not CFUN1, iperf will terminal");
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
nBytes = recvfrom( sockfd, buffer, IPERF_TEST_BUFFER_SIZE, 0, (struct sockaddr *) &cliaddr,
|
||
|
(socklen_t *) &cliLen );
|
||
|
|
||
|
udpHdr = (IperfUdpDatagram *) buffer;
|
||
|
udpHdrId = (INT32) ntohl( udpHdr->pkgId );
|
||
|
|
||
|
pktCount = IperfCalculateResult( nBytes, pktCount, 0 );
|
||
|
|
||
|
if(nBytes > 0)
|
||
|
{
|
||
|
if(IP_IS_V4(&serverParam->destAddr))
|
||
|
{
|
||
|
pktCount = IperfCalculateAddHeader(IPERF_STREAM_DOMAIN_IP4, IPERF_STREAM_PROTOCOL_UDP, pktCount);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
pktCount = IperfCalculateAddHeader(IPERF_STREAM_DOMAIN_IP6, IPERF_STREAM_PROTOCOL_UDP, pktCount);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//record the time when rcv the first packet
|
||
|
if( pktCount.times == 1 )
|
||
|
{
|
||
|
IperfGetCurrentTime( &t1, &t1_ms );
|
||
|
}
|
||
|
|
||
|
IperfGetCurrentTime( &currTime, 0 );
|
||
|
|
||
|
// Report by second
|
||
|
if( intervalTag > 0 )
|
||
|
{
|
||
|
if( currTime - offsetTime1 > 0 )
|
||
|
{
|
||
|
tmpRptNum = (((int)(currTime - offsetTime1)) / intervalTag);
|
||
|
if(tmpRptNum > 0)
|
||
|
{
|
||
|
if( tmpRptNum == totalRptNum)
|
||
|
{
|
||
|
|
||
|
nmIperfResult.mode = NM_IPERF_MODE_SERVER;
|
||
|
nmIperfResult.result = NM_IPERF_ONE_REPORT_SUCCESS;
|
||
|
nmIperfResult.dataNum = pktCount.Bytes - tmpCount.Bytes;
|
||
|
nmIperfResult.bandwidth = (((pktCount.Bytes - tmpCount.Bytes) * 8)/intervalTag);
|
||
|
|
||
|
ECOMM_TRACE(UNILOG_TCPIP_APP, IperfUdpRunServer_report_1, P_SIG, 2, "iperf udp server report,send %u bytes payload packet, bandwidth %u bps", nmIperfResult.dataNum, nmIperfResult.bandwidth);
|
||
|
|
||
|
AppMgrSendIperfResultInd(&nmIperfResult, serverParam->reqHandle);
|
||
|
|
||
|
tmpCount = IperfCopyCount( pktCount, tmpCount );
|
||
|
|
||
|
totalRptNum = tmpRptNum + 1;
|
||
|
}
|
||
|
else if(tmpRptNum > totalRptNum)
|
||
|
{
|
||
|
nmIperfResult.mode = NM_IPERF_MODE_SERVER;
|
||
|
nmIperfResult.result = NM_IPERF_ONE_REPORT_SUCCESS;
|
||
|
nmIperfResult.dataNum = pktCount.Bytes - tmpCount.Bytes;
|
||
|
nmIperfResult.bandwidth = (((pktCount.Bytes - tmpCount.Bytes) * 8)/(intervalTag *(tmpRptNum - totalRptNum + 1)));
|
||
|
|
||
|
ECOMM_TRACE(UNILOG_TCPIP_APP, IperfUdpRunServer_report_2, P_SIG, 2, "iperf udp server report,send %u bytes payload packet, bandwidth %u bps", nmIperfResult.dataNum, nmIperfResult.bandwidth);
|
||
|
|
||
|
AppMgrSendIperfResultInd(&nmIperfResult, serverParam->reqHandle);
|
||
|
|
||
|
tmpCount = IperfCopyCount( pktCount, tmpCount );
|
||
|
|
||
|
totalRptNum = tmpRptNum + 1;
|
||
|
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//rcv the fisrt valid udp packet
|
||
|
if( (isTestStarted == 0) && (udpHdrId > 0) && (nBytes > 0) )
|
||
|
{
|
||
|
isTestStarted = 1;
|
||
|
}//rcf the last packet
|
||
|
else if ( (udpHdrId < 0) && (isTestStarted == 1) )
|
||
|
{ // the last package
|
||
|
INT32 oldFlag = 0;
|
||
|
|
||
|
// print out result
|
||
|
//TODO: need to send the correct report to client-side, flag = 0 means the report is ignored.
|
||
|
//if( udpHdrId < 0 )
|
||
|
//{
|
||
|
oldFlag = clientHdrTrans.flags;
|
||
|
clientHdrTrans.flags = (INT32) 0;
|
||
|
|
||
|
// send the server report to client-side
|
||
|
sendto( sockfd, buffer, nBytes, 0, (struct sockaddr *) &cliaddr, cliLen );
|
||
|
clientHdrTrans.flags = oldFlag;
|
||
|
//}
|
||
|
|
||
|
clientHdr = (IperfClientHeader *) &buffer[12];
|
||
|
clientHdrTrans.flags = (INT32) (ntohl( clientHdr->flags ));
|
||
|
|
||
|
// Tradeoff mode
|
||
|
if( IPERF_HEADER_VERSION1 & clientHdrTrans.flags )
|
||
|
{
|
||
|
ECOMM_TRACE(UNILOG_TCPIP_APP, IperfUdpRunServer_6, P_WARNING, 0, "Tradeoff mode, client-side not support");
|
||
|
}
|
||
|
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
//check whether rcv stop command
|
||
|
if(bIperfSrvTerminRunning)
|
||
|
{
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
//check whether the total rcv timer timeout
|
||
|
if((currTime - offsetTime1 > rcvTime) && (currTime > offsetTime1))
|
||
|
{
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
//check socket error and is not timeout
|
||
|
if( nBytes <= 0 && sock_get_errno(sockfd) != ETIME)
|
||
|
{
|
||
|
ECOMM_TRACE(UNILOG_TCPIP_APP, IperfUdpRunServer_7, P_WARNING, 0, "iperf UDP server socket rcv error");
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
}while(TRUE);
|
||
|
|
||
|
} while (FALSE);
|
||
|
|
||
|
//the end report
|
||
|
IperfGetCurrentTime( &t2, &t2_ms );
|
||
|
nmIperfResult.mode = NM_IPERF_MODE_SERVER;
|
||
|
nmIperfResult.result = NM_IPERF_END_REPORT_SUCCESS;
|
||
|
nmIperfResult.dataNum = pktCount.Bytes;
|
||
|
if(pktCount.times > 0)
|
||
|
{
|
||
|
if(t2 > t1)
|
||
|
{
|
||
|
nmIperfResult.bandwidth = ((pktCount.Bytes * 8)/(t2 - t1));
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if(t2_ms > t1_ms)
|
||
|
{
|
||
|
nmIperfResult.bandwidth = ((pktCount.Bytes * 8 * 1000)/(t2_ms - t1_ms));
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
nmIperfResult.bandwidth = 0;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
nmIperfResult.bandwidth = 0;
|
||
|
}
|
||
|
AppMgrSendIperfResultInd(&nmIperfResult, serverParam->reqHandle);
|
||
|
|
||
|
ECOMM_TRACE(UNILOG_TCPIP_APP, IperfUdpRunServer_8, P_SIG, 2, "iperf UDP server report,TOTAL receive %u bytes payload packet, bandwidth %u bps", nmIperfResult.dataNum, nmIperfResult.bandwidth);
|
||
|
|
||
|
close( sockfd );
|
||
|
freeEc( buffer );
|
||
|
bIperfSrvTerminRunning = 0;
|
||
|
iperfSrvTask = NULL;
|
||
|
bIperfSrvIsGoingOn = 0;
|
||
|
|
||
|
/* before iperf task exit, should allow to enter HIB/Sleep2, and release hander */
|
||
|
pmuRet = slpManPlatVoteEnableSleep(iperfPmuHdr, SLP_SLP2_STATE);
|
||
|
OsaCheck(pmuRet == RET_TRUE, pmuRet, 0, 0);
|
||
|
|
||
|
pmuRet = slpManGivebackPlatVoteHandle(iperfPmuHdr);
|
||
|
OsaCheck(pmuRet == RET_TRUE, pmuRet, 0, 0);
|
||
|
|
||
|
ECOMM_TRACE(UNILOG_TCPIP_APP, IperfUdpRunServer_9, P_SIG, 0, "iperf UDP server terminal");
|
||
|
|
||
|
osThreadExit();
|
||
|
}
|
||
|
|
||
|
void IperfTcpRunServer( void *arg)
|
||
|
{
|
||
|
NmIperfReq * serverParam = (NmIperfReq *)arg;
|
||
|
INT32 listenfd, connfd;
|
||
|
struct sockaddr_in cliaddr;
|
||
|
socklen_t clilen;
|
||
|
INT32 serverPort;
|
||
|
IperfCount pktCount = {0, 0, 0, 0, 0};
|
||
|
IperfCount tmpCount = {0, 0, 0, 0, 0};
|
||
|
INT32 nBytes = 0;
|
||
|
UINT16 rcvTime;
|
||
|
UINT32 totalRptNum = 1;
|
||
|
UINT32 tmpRptNum = 0;
|
||
|
UINT32 intervalTag;
|
||
|
UINT32 rcvTimeout;
|
||
|
INT32 ret;
|
||
|
|
||
|
slpManRet_t pmuRet = RET_UNKNOW_FALSE;
|
||
|
UINT8 iperfPmuHdr = 0;
|
||
|
|
||
|
UINT32 t1,t1_ms,t2,t2_ms,currTime;
|
||
|
|
||
|
struct NmAtiIperfResultIndTag nmIperfResult;
|
||
|
memset(&nmIperfResult, 0, sizeof(struct NmAtiIperfResultIndTag));
|
||
|
|
||
|
//init setting
|
||
|
if(serverParam->rptIntervalPresent && serverParam->rptIntervalS > 0)
|
||
|
{
|
||
|
intervalTag = serverParam->rptIntervalS;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
intervalTag = IPERF_DEFAULT_REPORT_INTERVAL;
|
||
|
}
|
||
|
|
||
|
if(serverParam->durationPresent && serverParam->durationS > 0)
|
||
|
{
|
||
|
rcvTime = serverParam->durationS;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
rcvTime = IPERF_MAX_SEND_RCV_TIME;
|
||
|
}
|
||
|
|
||
|
if(serverParam->port > 0)
|
||
|
{
|
||
|
serverPort = serverParam->port;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
serverPort = IPERF_DEFAULT_PORT;
|
||
|
}
|
||
|
|
||
|
if(intervalTag < IPERF_SERVER_RECEIVE_TIMEOUT)
|
||
|
{
|
||
|
rcvTimeout = intervalTag;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
rcvTimeout = IPERF_SERVER_RECEIVE_TIMEOUT;
|
||
|
}
|
||
|
|
||
|
|
||
|
ECOMM_TRACE(UNILOG_TCPIP_APP, IperfTcpRunServer_1, P_SIG, 0, "iperf tcp server task start runing");
|
||
|
|
||
|
//init rcv buffer
|
||
|
CHAR *buffer = (CHAR*) mallocEc( IPERF_TEST_BUFFER_SIZE );
|
||
|
if(!buffer)
|
||
|
{
|
||
|
ECOMM_TRACE(UNILOG_TCPIP_APP, IperfTcpRunServer_2, P_WARNING, 0, "IPERF tcp server malloc buffer fail!");
|
||
|
nmIperfResult.mode = NM_IPERF_MODE_SERVER;
|
||
|
nmIperfResult.result = NM_IPERF_MALLOC_ERROR;
|
||
|
AppMgrSendIperfResultInd(&nmIperfResult, serverParam->reqHandle);
|
||
|
|
||
|
iperfSrvTask = NULL;
|
||
|
bIperfSrvIsGoingOn = 0;
|
||
|
osThreadExit();
|
||
|
}
|
||
|
|
||
|
|
||
|
// Create a new TCP connection handle
|
||
|
ret = IperfSetupTcpServerSocket(&listenfd, serverPort, rcvTimeout, &serverParam->destAddr);
|
||
|
if(ret != 0)
|
||
|
{
|
||
|
ECOMM_TRACE(UNILOG_TCPIP_APP, IperfTcpRunServer_3, P_WARNING, 0, "IPERF tcp server setup socket fail!");
|
||
|
nmIperfResult.mode = NM_IPERF_MODE_SERVER;
|
||
|
nmIperfResult.result = ret;
|
||
|
AppMgrSendIperfResultInd(&nmIperfResult, serverParam->reqHandle);
|
||
|
|
||
|
iperfSrvTask = NULL;
|
||
|
bIperfSrvIsGoingOn = 0;
|
||
|
freeEc(buffer);
|
||
|
osThreadExit();
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* start iperf, iperf task don't allow to enter HIB/Sleep2 state before iperf terminated
|
||
|
*/
|
||
|
pmuRet = slpManApplyPlatVoteHandle("iperfserver", &iperfPmuHdr);
|
||
|
OsaCheck(pmuRet == RET_TRUE, pmuRet, 0, 0);
|
||
|
|
||
|
pmuRet = slpManPlatVoteDisableSleep(iperfPmuHdr, SLP_SLP2_STATE);
|
||
|
OsaCheck(pmuRet == RET_TRUE, pmuRet, 0, 0);
|
||
|
|
||
|
do {
|
||
|
|
||
|
do {
|
||
|
|
||
|
// ait for an incoming connection
|
||
|
if ( (connfd = accept( listenfd, (struct sockaddr *) &cliaddr, &clilen )) != -1 )
|
||
|
{
|
||
|
|
||
|
IperfGetCurrentTime( &t1, &t1_ms);
|
||
|
|
||
|
//Connection
|
||
|
do {
|
||
|
|
||
|
//check pdn status first
|
||
|
if(!psDailBeCfun1State())
|
||
|
{
|
||
|
ECOMM_TRACE(UNILOG_TCPIP_APP, IperfTcpRunServer_4, P_WARNING, 0, "Not Cfun1, iperf will terminal");
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
nBytes = recv( connfd, buffer, IPERF_TEST_BUFFER_SIZE, 0 );
|
||
|
|
||
|
pktCount = IperfCalculateResult( nBytes, pktCount, 0 );
|
||
|
|
||
|
if(nBytes > 0)
|
||
|
{
|
||
|
if(IP_IS_V4(&serverParam->destAddr))
|
||
|
{
|
||
|
pktCount = IperfCalculateAddHeader(IPERF_STREAM_DOMAIN_IP4, IPERF_STREAM_PROTOCOL_TCP, pktCount);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
pktCount = IperfCalculateAddHeader(IPERF_STREAM_DOMAIN_IP6, IPERF_STREAM_PROTOCOL_TCP, pktCount);
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
ECOMM_TRACE(UNILOG_TCPIP_APP, IperfTcpRunServer_5, P_WARNING, 0, "iperf tcp rcv fail");
|
||
|
}
|
||
|
|
||
|
IperfGetCurrentTime( &currTime, 0 );
|
||
|
if ( intervalTag > 0 )
|
||
|
{
|
||
|
if( currTime - t1 > 0 )
|
||
|
{
|
||
|
tmpRptNum = (((int)(currTime - t1)) / intervalTag);
|
||
|
if(tmpRptNum > 0)
|
||
|
{
|
||
|
if( tmpRptNum == totalRptNum)
|
||
|
{
|
||
|
|
||
|
nmIperfResult.mode = NM_IPERF_MODE_SERVER;
|
||
|
nmIperfResult.result = NM_IPERF_ONE_REPORT_SUCCESS;
|
||
|
nmIperfResult.dataNum = pktCount.Bytes - tmpCount.Bytes;
|
||
|
nmIperfResult.bandwidth = (((pktCount.Bytes - tmpCount.Bytes) * 8)/intervalTag);
|
||
|
|
||
|
ECOMM_TRACE(UNILOG_TCPIP_APP, IperfTcpRunServer_report_1, P_SIG, 2, "iperf tcp server report,send %u bytes payload packet, bandwidth %u bps", nmIperfResult.dataNum, nmIperfResult.bandwidth);
|
||
|
|
||
|
AppMgrSendIperfResultInd(&nmIperfResult, serverParam->reqHandle);
|
||
|
|
||
|
tmpCount = IperfCopyCount( pktCount, tmpCount );
|
||
|
|
||
|
totalRptNum = tmpRptNum + 1;
|
||
|
}
|
||
|
else if(tmpRptNum > totalRptNum)
|
||
|
{
|
||
|
nmIperfResult.mode = NM_IPERF_MODE_SERVER;
|
||
|
nmIperfResult.result = NM_IPERF_ONE_REPORT_SUCCESS;
|
||
|
nmIperfResult.dataNum = pktCount.Bytes - tmpCount.Bytes;
|
||
|
nmIperfResult.bandwidth = (((pktCount.Bytes - tmpCount.Bytes) * 8)/(intervalTag *(tmpRptNum - totalRptNum + 1)));
|
||
|
|
||
|
ECOMM_TRACE(UNILOG_TCPIP_APP, IperfTcpRunServer_report_2, P_SIG, 2, "iperf tcp server report,send %u bytes payload packet, bandwidth %u bps", nmIperfResult.dataNum, nmIperfResult.bandwidth);
|
||
|
|
||
|
AppMgrSendIperfResultInd(&nmIperfResult, serverParam->reqHandle);
|
||
|
|
||
|
tmpCount = IperfCopyCount( pktCount, tmpCount );
|
||
|
|
||
|
totalRptNum = tmpRptNum + 1;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// check whether rcv stop command
|
||
|
if(bIperfSrvTerminRunning)
|
||
|
{
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
//check whether the total rcv timer timeout
|
||
|
if((currTime - t1 > rcvTime) && (currTime > t1))
|
||
|
{
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
//check socket error and is not timeout
|
||
|
if( nBytes <= 0 && sock_get_errno(connfd) != ERR_TIMEOUT)
|
||
|
{
|
||
|
break;
|
||
|
}
|
||
|
}while(TRUE);
|
||
|
//if the connfd socket error, try accept again
|
||
|
close( connfd );
|
||
|
}
|
||
|
|
||
|
// check whether rcv stop command
|
||
|
if(bIperfSrvTerminRunning)
|
||
|
{
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
//check whether the total rcv timer timeout
|
||
|
if((currTime - t1 > rcvTime) && (currTime > t1))
|
||
|
{
|
||
|
break;
|
||
|
}
|
||
|
}while(TRUE);
|
||
|
} while (FALSE); //Loop just once
|
||
|
|
||
|
//the end report
|
||
|
IperfGetCurrentTime( &t2, &t2_ms);
|
||
|
nmIperfResult.mode = NM_IPERF_MODE_SERVER;
|
||
|
nmIperfResult.result = NM_IPERF_END_REPORT_SUCCESS;
|
||
|
nmIperfResult.dataNum = pktCount.Bytes;
|
||
|
if(pktCount.times > 0)
|
||
|
{
|
||
|
if(t2 > t1)
|
||
|
{
|
||
|
nmIperfResult.bandwidth = ((pktCount.Bytes * 8)/(t2 - t1));
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if(t2_ms > t1_ms)
|
||
|
{
|
||
|
nmIperfResult.bandwidth = ((pktCount.Bytes * 8 * 1000)/(t2_ms - t1_ms));
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
nmIperfResult.bandwidth = 0;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
nmIperfResult.bandwidth = 0;
|
||
|
}
|
||
|
|
||
|
AppMgrSendIperfResultInd(&nmIperfResult, serverParam->reqHandle);
|
||
|
|
||
|
ECOMM_TRACE(UNILOG_TCPIP_APP, IperfTcpRunServer_7, P_SIG, 2, "iperf tcp server report,TOTAL receive %u bytes payload packet, bandwidth %u bps", nmIperfResult.dataNum, nmIperfResult.bandwidth);
|
||
|
|
||
|
close( listenfd );
|
||
|
freeEc( buffer );
|
||
|
bIperfSrvTerminRunning = 0;
|
||
|
iperfSrvTask = NULL;
|
||
|
bIperfSrvIsGoingOn = 0;
|
||
|
|
||
|
/* before iperf task exit, should allow to enter HIB/Sleep2, and release hander */
|
||
|
pmuRet = slpManPlatVoteEnableSleep(iperfPmuHdr, SLP_SLP2_STATE);
|
||
|
OsaCheck(pmuRet == RET_TRUE, pmuRet, 0, 0);
|
||
|
|
||
|
pmuRet = slpManGivebackPlatVoteHandle(iperfPmuHdr);
|
||
|
OsaCheck(pmuRet == RET_TRUE, pmuRet, 0, 0);
|
||
|
|
||
|
ECOMM_TRACE(UNILOG_TCPIP_APP, IperfTcpRunServer_8, P_SIG, 0, "iperf tcp server terminal");
|
||
|
|
||
|
osThreadExit();
|
||
|
|
||
|
}
|
||
|
|
||
|
void IperfTcpRunClient( void* arg )
|
||
|
{
|
||
|
|
||
|
NmIperfReq *clientParam = (NmIperfReq *)arg;
|
||
|
INT32 sockfd;
|
||
|
IperfCount pktCount = {0, 0, 0, 0, 0};
|
||
|
IperfCount tmpCount = {0, 0, 0, 0, 0};
|
||
|
INT32 nBytes = 0;
|
||
|
INT32 winSize, sendTime, serverPort;
|
||
|
UINT32 t1,t1_ms,t2,t2_ms, currTime, bw, pktDelay = 0;
|
||
|
INT32 totalSend = 0x7FFFFFFF;
|
||
|
UINT32 totalRptNum = 1;
|
||
|
UINT32 tmpRptNum = 0;
|
||
|
INT32 ret;
|
||
|
INT32 sockErr;
|
||
|
|
||
|
BOOL bAlwaysSend = FALSE;
|
||
|
|
||
|
slpManRet_t pmuRet = RET_UNKNOW_FALSE;
|
||
|
UINT8 iperfPmuHdr = 0;
|
||
|
UINT32 intervalTag;
|
||
|
|
||
|
//Statistics init
|
||
|
struct NmAtiIperfResultIndTag nmIperfResult;
|
||
|
memset(&nmIperfResult, 0, sizeof(struct NmAtiIperfResultIndTag));
|
||
|
|
||
|
//init setting
|
||
|
if(clientParam->rptIntervalPresent && clientParam->rptIntervalS > 0)
|
||
|
{
|
||
|
intervalTag = clientParam->rptIntervalS; /* the tag of parameter "-i" */
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
intervalTag = IPERF_DEFAULT_REPORT_INTERVAL;
|
||
|
}
|
||
|
|
||
|
if(clientParam->payloadSizePresent && clientParam->payloadSize >= 36)
|
||
|
{
|
||
|
winSize = ((clientParam->payloadSize > IPERF_DEFAULT_PAYLOAD_SIZE) ? IPERF_DEFAULT_PAYLOAD_SIZE : clientParam->payloadSize);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
winSize = IPERF_DEFAULT_PAYLOAD_SIZE;
|
||
|
}
|
||
|
|
||
|
if(clientParam->pkgNumPresent && clientParam->pkgNum > 0)
|
||
|
{
|
||
|
totalSend = clientParam->pkgNum * winSize; /* the total number of transmit */
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// totalSend = IPERF_TOTAL_SEND_MAX;
|
||
|
bAlwaysSend = TRUE;
|
||
|
}
|
||
|
|
||
|
if(clientParam->durationPresent && clientParam->durationS > 0)
|
||
|
{
|
||
|
sendTime = clientParam->durationS;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
sendTime = IPERF_MAX_SEND_RCV_TIME;
|
||
|
}
|
||
|
|
||
|
if(clientParam->port > 0)
|
||
|
{
|
||
|
serverPort = clientParam->port;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
serverPort = IPERF_DEFAULT_PORT;
|
||
|
}
|
||
|
|
||
|
if (clientParam->tptPresent && clientParam->tpt > 0)
|
||
|
{
|
||
|
/* the input is bps, but bw is Bps (bytes per second)*/
|
||
|
if ((clientParam->tpt) & 0x07)
|
||
|
{
|
||
|
bw = ((clientParam->tpt) >> 3) + 1;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
bw = (clientParam->tpt) >> 3;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
bw = IPERF_DEFAULT_TPT; //8bps
|
||
|
}
|
||
|
|
||
|
ECOMM_TRACE(UNILOG_TCPIP_APP, IperfTcpRunClient_1, P_SIG, 0, "iperf tcp client task start runing");
|
||
|
|
||
|
//init send buffer
|
||
|
CHAR *buffer = (CHAR*) mallocEc( winSize );
|
||
|
if(!buffer)
|
||
|
{
|
||
|
ECOMM_TRACE(UNILOG_TCPIP_APP, IperfTcpRunClient_2, P_WARNING, 0, "iperf tcp client malloc buffer fail");
|
||
|
|
||
|
nmIperfResult.mode = NM_IPERF_MODE_CLIENT;
|
||
|
nmIperfResult.result = NM_IPERF_MALLOC_ERROR;
|
||
|
AppMgrSendIperfResultInd(&nmIperfResult, clientParam->reqHandle);
|
||
|
|
||
|
iperfCLtTask = NULL;
|
||
|
bIperfCltIsGoingOn = 0;
|
||
|
osThreadExit();
|
||
|
}
|
||
|
|
||
|
//calc the send packet delay depend on bw setting
|
||
|
if ( bw > 0 )
|
||
|
{
|
||
|
pktDelay = (1000 * winSize) / bw;
|
||
|
}
|
||
|
|
||
|
|
||
|
//setup socket connection
|
||
|
if(clientParam->destAddrPresent)
|
||
|
{
|
||
|
ret = IperfSetupClientSocket(&sockfd, IPERF_STREAM_PROTOCOL_TCP, serverPort, &clientParam->destAddr);
|
||
|
if(ret != 0)
|
||
|
{
|
||
|
ECOMM_TRACE(UNILOG_TCPIP_APP, IperfTcpRunClient_3, P_WARNING, 0, "iperf tcp client socket setup fail");
|
||
|
|
||
|
nmIperfResult.mode = NM_IPERF_MODE_CLIENT;
|
||
|
nmIperfResult.result = ret;
|
||
|
AppMgrSendIperfResultInd(&nmIperfResult, clientParam->reqHandle);
|
||
|
|
||
|
iperfCLtTask = NULL;
|
||
|
bIperfCltIsGoingOn = 0;
|
||
|
freeEc(buffer);
|
||
|
osThreadExit();
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
ECOMM_TRACE(UNILOG_TCPIP_APP, IperfTcpRunClient_4, P_WARNING, 0, "iperf tcp client dest addr is not present");
|
||
|
|
||
|
nmIperfResult.mode = NM_IPERF_MODE_CLIENT;
|
||
|
nmIperfResult.result = NM_IPERF_PARAM_ERROR;
|
||
|
AppMgrSendIperfResultInd(&nmIperfResult, clientParam->reqHandle);
|
||
|
|
||
|
iperfCLtTask = NULL;
|
||
|
bIperfCltIsGoingOn = 0;
|
||
|
freeEc(buffer);
|
||
|
osThreadExit();
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* start iperf, iperf task don't allow to enter HIB/Sleep2 state before iperf terminated
|
||
|
*/
|
||
|
pmuRet = slpManApplyPlatVoteHandle("iperfclient", &iperfPmuHdr);
|
||
|
OsaCheck(pmuRet == RET_TRUE, pmuRet, 0, 0);
|
||
|
|
||
|
pmuRet = slpManPlatVoteDisableSleep(iperfPmuHdr, SLP_SLP2_STATE);
|
||
|
OsaCheck(pmuRet == RET_TRUE, pmuRet, 0, 0);
|
||
|
|
||
|
IperfGetCurrentTime( &t1, &t1_ms);
|
||
|
|
||
|
do {
|
||
|
//check pdn status first
|
||
|
if(!psDailBeCfun1State())
|
||
|
{
|
||
|
ECOMM_TRACE(UNILOG_TCPIP_APP, IperfTcpRunClient_5, P_WARNING, 0, "Not CFUN1 state, iperf will terminal");
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
nBytes = send( sockfd, buffer, winSize, 0 );
|
||
|
|
||
|
pktCount = IperfCalculateResult( nBytes, pktCount, 0 );
|
||
|
|
||
|
if(nBytes > 0)
|
||
|
{
|
||
|
if(IP_IS_V4(&clientParam->destAddr))
|
||
|
{
|
||
|
pktCount = IperfCalculateAddHeader(IPERF_STREAM_DOMAIN_IP4, IPERF_STREAM_PROTOCOL_TCP, pktCount);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
pktCount = IperfCalculateAddHeader(IPERF_STREAM_DOMAIN_IP6, IPERF_STREAM_PROTOCOL_TCP, pktCount);
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
sockErr = sock_get_errno(sockfd);
|
||
|
ECOMM_TRACE(UNILOG_TCPIP_APP, IperfTcpRunClient_6, P_ERROR, 1, "iperf tcp client send packet fail,error code %d", sockErr);
|
||
|
|
||
|
if(socket_error_is_fatal(sockErr))
|
||
|
{
|
||
|
ECOMM_TRACE(UNILOG_TCPIP_APP, IperfTcpRunClient_7, P_ERROR, 1, "iperf tcp client send packet fail,the error %d is fata error ,exist", sockErr);
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
IperfmSleep( pktDelay );
|
||
|
|
||
|
IperfGetCurrentTime( &currTime, 0 );
|
||
|
|
||
|
if ( intervalTag > 0 )
|
||
|
{
|
||
|
if( currTime - t1 > 0 )
|
||
|
{
|
||
|
tmpRptNum = (((int)(currTime - t1)) / intervalTag);
|
||
|
if(tmpRptNum > 0)
|
||
|
{
|
||
|
if( tmpRptNum == totalRptNum)
|
||
|
{
|
||
|
|
||
|
nmIperfResult.mode = NM_IPERF_MODE_CLIENT;
|
||
|
nmIperfResult.result = NM_IPERF_ONE_REPORT_SUCCESS;
|
||
|
nmIperfResult.dataNum = pktCount.Bytes - tmpCount.Bytes;
|
||
|
nmIperfResult.bandwidth = (((pktCount.Bytes - tmpCount.Bytes) * 8)/intervalTag);
|
||
|
|
||
|
ECOMM_TRACE(UNILOG_TCPIP_APP, IperfTcpRunClient_report_1, P_SIG, 2, "iperf tcp client report,send %u bytes payload packet, bandwidth %u bps", nmIperfResult.dataNum, nmIperfResult.bandwidth);
|
||
|
|
||
|
AppMgrSendIperfResultInd(&nmIperfResult, clientParam->reqHandle);
|
||
|
|
||
|
tmpCount = IperfCopyCount( pktCount, tmpCount );
|
||
|
|
||
|
totalRptNum = tmpRptNum + 1;
|
||
|
}
|
||
|
else if(tmpRptNum > totalRptNum)
|
||
|
{
|
||
|
nmIperfResult.mode = NM_IPERF_MODE_CLIENT;
|
||
|
nmIperfResult.result = NM_IPERF_ONE_REPORT_SUCCESS;
|
||
|
nmIperfResult.dataNum = pktCount.Bytes - tmpCount.Bytes;
|
||
|
nmIperfResult.bandwidth = (((pktCount.Bytes - tmpCount.Bytes) * 8)/(intervalTag *(tmpRptNum - totalRptNum + 1)));
|
||
|
|
||
|
ECOMM_TRACE(UNILOG_TCPIP_APP, IperfTcpRunClient_report_2, P_SIG, 2, "iperf tcp client report,send %u bytes payload packet, bandwidth %u bps", nmIperfResult.dataNum, nmIperfResult.bandwidth);
|
||
|
|
||
|
AppMgrSendIperfResultInd(&nmIperfResult, clientParam->reqHandle);
|
||
|
|
||
|
tmpCount = IperfCopyCount( pktCount, tmpCount );
|
||
|
|
||
|
totalRptNum = tmpRptNum + 1;
|
||
|
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//check whether packet has send complete
|
||
|
if(bAlwaysSend == FALSE)
|
||
|
{
|
||
|
if(nBytes > 0)
|
||
|
{
|
||
|
totalSend -= nBytes;
|
||
|
}
|
||
|
if(totalSend <= 0)
|
||
|
{
|
||
|
ECOMM_TRACE(UNILOG_TCPIP_APP, IperfTcpRunClient_9, P_SIG, 0, "iperf tcp client send total packet finish");
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//check whether rcv stop command
|
||
|
if(bIperfCltTerminRunning)
|
||
|
{
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
//check whether the total send timer timeout
|
||
|
if((currTime - t1 > sendTime) && (currTime > t1))
|
||
|
{
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
|
||
|
} while(TRUE);
|
||
|
|
||
|
//the end report
|
||
|
IperfGetCurrentTime( &t2, &t2_ms);
|
||
|
nmIperfResult.mode = NM_IPERF_MODE_CLIENT;
|
||
|
nmIperfResult.result = NM_IPERF_END_REPORT_SUCCESS;
|
||
|
nmIperfResult.dataNum = pktCount.Bytes;
|
||
|
if(pktCount.times > 0) {
|
||
|
if(t2 > t1)
|
||
|
{
|
||
|
nmIperfResult.bandwidth = ((pktCount.Bytes * 8)/(t2-t1));
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if(t2_ms > t1_ms)
|
||
|
{
|
||
|
nmIperfResult.bandwidth = ((pktCount.Bytes * 8 * 1000)/(t2_ms-t1_ms));
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
nmIperfResult.bandwidth = 0;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
nmIperfResult.bandwidth = 0;
|
||
|
}
|
||
|
AppMgrSendIperfResultInd(&nmIperfResult, clientParam->reqHandle);
|
||
|
|
||
|
ECOMM_TRACE(UNILOG_TCPIP_APP, IperfTcpRunClient_10, P_SIG, 2, "iperf tcp client report,TOTAL send %u bytes payload packet, bandwidth %u bps", nmIperfResult.dataNum, nmIperfResult.bandwidth);
|
||
|
|
||
|
close( sockfd );
|
||
|
freeEc(buffer);
|
||
|
bIperfCltTerminRunning = 0;
|
||
|
iperfCLtTask = NULL;
|
||
|
bIperfCltIsGoingOn = 0;
|
||
|
|
||
|
/* before iperf task exit, should allow to enter HIB/Sleep2, and release hander */
|
||
|
pmuRet = slpManPlatVoteEnableSleep(iperfPmuHdr, SLP_SLP2_STATE);
|
||
|
OsaCheck(pmuRet == RET_TRUE, pmuRet, 0, 0);
|
||
|
|
||
|
pmuRet = slpManGivebackPlatVoteHandle(iperfPmuHdr);
|
||
|
OsaCheck(pmuRet == RET_TRUE, pmuRet, 0, 0);
|
||
|
|
||
|
ECOMM_TRACE(UNILOG_TCPIP_APP, IperfTcpRunClient_11, P_SIG, 0, "iperf tcp client terminal");
|
||
|
|
||
|
osThreadExit();
|
||
|
|
||
|
}
|
||
|
|
||
|
void IperfUdpRunClient( void* arg )
|
||
|
{
|
||
|
|
||
|
NmIperfReq *clientParam = (NmIperfReq *)arg;
|
||
|
|
||
|
INT32 sockfd;
|
||
|
INT32 ret;
|
||
|
IperfCount pktCount = {0, 0, 0, 0, 0};
|
||
|
IperfCount tmpCount = {0, 0, 0, 0, 0};
|
||
|
INT32 nBytes = 0;
|
||
|
INT32 tradeoffTag = FALSE;
|
||
|
UINT32 dataSize, sendTime, serverPort;
|
||
|
UINT32 pktDelay = 0;
|
||
|
UINT32 pktDelayOffset = 0;
|
||
|
UINT32 totalRptNum = 1;
|
||
|
UINT32 tmpRptNum = 0;
|
||
|
|
||
|
UINT32 bw; //bandwidth, in Bps (Bytes per second)
|
||
|
UINT32 t1, t2, currTime, t1_ms,t2_ms,lastTick, currentTick, lastSleep, currentSleep = 0;
|
||
|
INT32 totalSend = 0x7FFFFFFF;
|
||
|
INT32 sockErr = 0, lastErr = 0;
|
||
|
|
||
|
BOOL bAlwaysSend = FALSE;
|
||
|
|
||
|
IperfUdpDatagram *udpHdr;
|
||
|
IperfClientHeader *clientHdr;
|
||
|
INT32 udpHdrId = 0;
|
||
|
|
||
|
slpManRet_t pmuRet = RET_UNKNOW_FALSE;
|
||
|
UINT8 iperfPmuHdr = 0;
|
||
|
UINT32 intervalTag;
|
||
|
|
||
|
struct NmAtiIperfResultIndTag nmIperfResult;
|
||
|
memset(&nmIperfResult, 0, sizeof(struct NmAtiIperfResultIndTag));
|
||
|
|
||
|
//init setting
|
||
|
if (clientParam->rptIntervalPresent && clientParam->rptIntervalS > 0)
|
||
|
{
|
||
|
intervalTag = clientParam->rptIntervalS;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
intervalTag = IPERF_DEFAULT_REPORT_INTERVAL;
|
||
|
}
|
||
|
|
||
|
if (clientParam->payloadSizePresent && clientParam->payloadSize >= 36)
|
||
|
{
|
||
|
dataSize = ((clientParam->payloadSize > IPERF_DEFAULT_PAYLOAD_SIZE) ? IPERF_DEFAULT_PAYLOAD_SIZE : clientParam->payloadSize);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
dataSize = IPERF_DEFAULT_PAYLOAD_SIZE;
|
||
|
}
|
||
|
|
||
|
if (clientParam->pkgNumPresent && clientParam->pkgNum > 0)
|
||
|
{
|
||
|
totalSend = clientParam->pkgNum * dataSize;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// totalSend = IPERF_TOTAL_SEND_MAX;
|
||
|
bAlwaysSend = TRUE;
|
||
|
}
|
||
|
|
||
|
if (clientParam->durationPresent && clientParam->durationS > 0)
|
||
|
{
|
||
|
sendTime = clientParam->durationS;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
sendTime = IPERF_MAX_SEND_RCV_TIME;
|
||
|
}
|
||
|
|
||
|
if (clientParam->port > 0)
|
||
|
{
|
||
|
serverPort = clientParam->port;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
serverPort = IPERF_DEFAULT_PORT;
|
||
|
}
|
||
|
|
||
|
if (clientParam->tptPresent && clientParam->tpt > 0)
|
||
|
{
|
||
|
/* the input is bps, but bw is Bps (bytes per second)*/
|
||
|
if ((clientParam->tpt) & 0x07)
|
||
|
{
|
||
|
bw = ((clientParam->tpt) >> 3) + 1;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
bw = (clientParam->tpt) >> 3;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
bw = IPERF_DEFAULT_TPT; //1KBps
|
||
|
}
|
||
|
|
||
|
ECOMM_TRACE(UNILOG_TCPIP_APP, IperfUdpRunClient_1, P_SIG, 0, "iperf udp client task start runing");
|
||
|
|
||
|
//init send buffer
|
||
|
CHAR *buffer = (CHAR*) mallocEc(dataSize);
|
||
|
if(!buffer)
|
||
|
{
|
||
|
ECOMM_TRACE(UNILOG_TCPIP_APP, IperfUdpRunClient_2, P_WARNING, 0, "iperf udp client malloc buffer fail");
|
||
|
|
||
|
nmIperfResult.mode = NM_IPERF_MODE_CLIENT;
|
||
|
nmIperfResult.result = NM_IPERF_MALLOC_ERROR;
|
||
|
AppMgrSendIperfResultInd(&nmIperfResult, clientParam->reqHandle);
|
||
|
|
||
|
iperfCLtTask = NULL;
|
||
|
bIperfCltIsGoingOn = 0;
|
||
|
osThreadExit();
|
||
|
}
|
||
|
memset(buffer, 0, dataSize);
|
||
|
|
||
|
//calc the send packet delay depend on the bw setting
|
||
|
if (bw > 0)
|
||
|
{
|
||
|
pktDelay = (1000 * dataSize)/bw;
|
||
|
|
||
|
// pkt_dalay add 1ms regularly to reduce the offset
|
||
|
pktDelayOffset = (((1000 * dataSize) % bw) * 10 / bw);
|
||
|
if( pktDelayOffset )
|
||
|
{
|
||
|
pktDelayOffset = 10 / pktDelayOffset;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//setup socket connection
|
||
|
if (clientParam->destAddrPresent)
|
||
|
{
|
||
|
ret = IperfSetupClientSocket(&sockfd, IPERF_STREAM_PROTOCOL_UDP, serverPort, &clientParam->destAddr);
|
||
|
if(ret != 0)
|
||
|
{
|
||
|
ECOMM_TRACE(UNILOG_TCPIP_APP, IperfUdpRunClient_3, P_WARNING, 0, "iperf udp client socket setup fail");
|
||
|
|
||
|
nmIperfResult.mode = NM_IPERF_MODE_CLIENT;
|
||
|
nmIperfResult.result = ret;
|
||
|
AppMgrSendIperfResultInd(&nmIperfResult, clientParam->reqHandle);
|
||
|
|
||
|
iperfCLtTask = NULL;
|
||
|
bIperfCltIsGoingOn = 0;
|
||
|
freeEc(buffer);
|
||
|
osThreadExit();
|
||
|
}
|
||
|
|
||
|
//enable udp socket high water without delay retry for iperf udp client service
|
||
|
UINT32 hwwdr = 1;
|
||
|
ioctl(sockfd, FIOHWODR, &hwwdr);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
ECOMM_TRACE(UNILOG_TCPIP_APP, IperfUdpRunClient_4, P_WARNING, 0, "iperf udp client dest addr is not present");
|
||
|
|
||
|
nmIperfResult.mode = NM_IPERF_MODE_CLIENT;
|
||
|
nmIperfResult.result = NM_IPERF_PARAM_ERROR;
|
||
|
AppMgrSendIperfResultInd(&nmIperfResult, clientParam->reqHandle);
|
||
|
|
||
|
iperfCLtTask = NULL;
|
||
|
bIperfCltIsGoingOn = 0;
|
||
|
freeEc(buffer);
|
||
|
osThreadExit();
|
||
|
}
|
||
|
|
||
|
|
||
|
// Init UDP data header
|
||
|
udpHdr = (IperfUdpDatagram *) &buffer[0];
|
||
|
clientHdr = (IperfClientHeader *) &buffer[12];
|
||
|
if( tradeoffTag == TRUE )
|
||
|
{
|
||
|
clientHdr->flags = htonl( IPERF_HEADER_VERSION1 );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
clientHdr->flags = 0;
|
||
|
}
|
||
|
clientHdr->numChannels = htonl( 1 );
|
||
|
clientHdr->portClient = htonl( serverPort );
|
||
|
clientHdr->buffLen = 0;
|
||
|
clientHdr->band = htonl(bw);
|
||
|
clientHdr->amounts = htonl((long )(sendTime * 100));
|
||
|
clientHdr->amounts &= htonl(0x7FFFFFFF);
|
||
|
|
||
|
/*
|
||
|
* start iperf, iperf task don't allow to enter HIB/Sleep2 state before iperf terminated
|
||
|
*/
|
||
|
pmuRet = slpManApplyPlatVoteHandle("iperfclient", &iperfPmuHdr);
|
||
|
OsaCheck(pmuRet == RET_TRUE, pmuRet, 0, 0);
|
||
|
|
||
|
pmuRet = slpManPlatVoteDisableSleep(iperfPmuHdr, SLP_SLP2_STATE);
|
||
|
OsaCheck(pmuRet == RET_TRUE, pmuRet, 0, 0);
|
||
|
|
||
|
IperfGetCurrentTime( &t1, &t1_ms );
|
||
|
lastTick = t1_ms;
|
||
|
lastSleep = 0;
|
||
|
|
||
|
do {
|
||
|
|
||
|
//check pdn status first
|
||
|
if(!psDailBeCfun1State())
|
||
|
{
|
||
|
ECOMM_TRACE(UNILOG_TCPIP_APP, IperfUdpRunClient_5, P_WARNING, 0, "Not cfun1 state, iperf will terminal");
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
udpHdr->pkgId = htonl( udpHdrId );
|
||
|
udpHdr->sec = htonl( (lastTick + lastSleep) / 1000 );
|
||
|
udpHdr->uSec = htonl( lastTick + lastSleep );
|
||
|
|
||
|
udpHdrId++;
|
||
|
|
||
|
nBytes = send(sockfd, buffer, dataSize, 0);
|
||
|
|
||
|
pktCount = IperfCalculateResult( nBytes, pktCount, 0 );
|
||
|
|
||
|
if (nBytes > 0)
|
||
|
{
|
||
|
lastErr = 0;
|
||
|
if(IP_IS_V4(&clientParam->destAddr))
|
||
|
{
|
||
|
pktCount = IperfCalculateAddHeader(IPERF_STREAM_DOMAIN_IP4, IPERF_STREAM_PROTOCOL_UDP, pktCount);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
pktCount = IperfCalculateAddHeader(IPERF_STREAM_DOMAIN_IP6, IPERF_STREAM_PROTOCOL_UDP, pktCount);
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
sockErr = sock_get_errno(sockfd);
|
||
|
|
||
|
/* reduce some warning print */
|
||
|
if (lastErr != sockErr)
|
||
|
{
|
||
|
ECOMM_TRACE(UNILOG_TCPIP_APP, IperfUdpRunClient_6, P_ERROR, 1,
|
||
|
"iperf udp client send packet fail, error code: %d", sockErr);
|
||
|
|
||
|
lastErr = sockErr;
|
||
|
}
|
||
|
|
||
|
if (socket_error_is_fatal(sockErr))
|
||
|
{
|
||
|
ECOMM_TRACE(UNILOG_TCPIP_APP, IperfUdpRunClient_7, P_ERROR, 1, "iperf udp client send packet fail,the error %d is fata error ,exist", sockErr);
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
IperfGetCurrentTime(&currTime, ¤tTick);
|
||
|
|
||
|
if (pktDelayOffset > 0)
|
||
|
{
|
||
|
if ((udpHdrId % pktDelayOffset) == 0)
|
||
|
{
|
||
|
currentSleep = pktDelay - (currentTick - lastTick - lastSleep) + 1;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
currentSleep = pktDelay - (currentTick - lastTick - lastSleep);
|
||
|
}
|
||
|
|
||
|
if ((INT32)currentSleep > 0)
|
||
|
{
|
||
|
IperfmSleep( currentSleep );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
currentSleep = 0;
|
||
|
}
|
||
|
|
||
|
lastTick = currentTick;
|
||
|
lastSleep = currentSleep;
|
||
|
|
||
|
if (intervalTag > 0)
|
||
|
{
|
||
|
if( currTime - t1 > 0 )
|
||
|
{
|
||
|
tmpRptNum = (((int)(currTime - t1)) / intervalTag);
|
||
|
if(tmpRptNum > 0)
|
||
|
{
|
||
|
if( tmpRptNum == totalRptNum)
|
||
|
{
|
||
|
|
||
|
nmIperfResult.mode = NM_IPERF_MODE_CLIENT;
|
||
|
nmIperfResult.result = NM_IPERF_ONE_REPORT_SUCCESS;
|
||
|
nmIperfResult.dataNum = pktCount.Bytes - tmpCount.Bytes;
|
||
|
nmIperfResult.bandwidth = (((pktCount.Bytes - tmpCount.Bytes) * 8)/intervalTag);
|
||
|
|
||
|
ECOMM_TRACE(UNILOG_TCPIP_APP, IperfUdpRunClient_report_1, P_SIG, 2, "iperf udp client report,send %u bytes payload packet, bandwidth %u bps", nmIperfResult.dataNum, nmIperfResult.bandwidth);
|
||
|
|
||
|
AppMgrSendIperfResultInd(&nmIperfResult, clientParam->reqHandle);
|
||
|
|
||
|
tmpCount = IperfCopyCount( pktCount, tmpCount );
|
||
|
|
||
|
totalRptNum = tmpRptNum + 1;
|
||
|
}
|
||
|
else if(tmpRptNum > totalRptNum)
|
||
|
{
|
||
|
nmIperfResult.mode = NM_IPERF_MODE_CLIENT;
|
||
|
nmIperfResult.result = NM_IPERF_ONE_REPORT_SUCCESS;
|
||
|
nmIperfResult.dataNum = pktCount.Bytes - tmpCount.Bytes;
|
||
|
nmIperfResult.bandwidth = (((pktCount.Bytes - tmpCount.Bytes) * 8)/(intervalTag *(tmpRptNum - totalRptNum + 1)));
|
||
|
|
||
|
ECOMM_TRACE(UNILOG_TCPIP_APP, IperfUdpRunClient_report_2, P_SIG, 2, "iperf udp client report,send %u bytes payload packet, bandwidth %u bps", nmIperfResult.dataNum, nmIperfResult.bandwidth);
|
||
|
|
||
|
AppMgrSendIperfResultInd(&nmIperfResult, clientParam->reqHandle);
|
||
|
|
||
|
tmpCount = IperfCopyCount( pktCount, tmpCount );
|
||
|
|
||
|
totalRptNum = tmpRptNum + 1;
|
||
|
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//check whether packet has sent complete
|
||
|
if(bAlwaysSend == FALSE)
|
||
|
{
|
||
|
if(nBytes > 0)
|
||
|
{
|
||
|
totalSend -= nBytes;
|
||
|
}
|
||
|
if(totalSend <= 0)
|
||
|
{
|
||
|
ECOMM_TRACE(UNILOG_TCPIP_APP, IperfUdpRunClient_9, P_SIG, 0, "iperf udp client send total packet finish");
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//check whether rcv stop command
|
||
|
if(bIperfCltTerminRunning)
|
||
|
{
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
//check whether the total send timer timeout
|
||
|
if((currTime - t1 > sendTime) && (currTime > t1))
|
||
|
{
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
|
||
|
} while(TRUE);
|
||
|
|
||
|
//the total end report
|
||
|
IperfGetCurrentTime( &t2, &t2_ms );
|
||
|
nmIperfResult.mode = NM_IPERF_MODE_CLIENT;
|
||
|
nmIperfResult.result = NM_IPERF_END_REPORT_SUCCESS;
|
||
|
nmIperfResult.dataNum = pktCount.Bytes;
|
||
|
if(pktCount.times > 0)
|
||
|
{
|
||
|
if(t2 > t1)
|
||
|
{
|
||
|
nmIperfResult.bandwidth = ((pktCount.Bytes * 8)/(t2-t1));
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if(t2_ms > t1_ms)
|
||
|
{
|
||
|
nmIperfResult.bandwidth = ((pktCount.Bytes * 8 * 1000)/(t2_ms-t1_ms));
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
nmIperfResult.bandwidth = 0;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
nmIperfResult.bandwidth = 0;
|
||
|
}
|
||
|
|
||
|
AppMgrSendIperfResultInd(&nmIperfResult, clientParam->reqHandle);
|
||
|
|
||
|
ECOMM_TRACE(UNILOG_TCPIP_APP, IperfUdpRunClient_10, P_SIG, 2, "iperf udp client report,TOTAL send %u bytes payload packet, bandwidth %u bps", nmIperfResult.dataNum, nmIperfResult.bandwidth);
|
||
|
|
||
|
// send the last datagram
|
||
|
udpHdrId = (-udpHdrId);
|
||
|
udpHdr->pkgId = htonl( udpHdrId );
|
||
|
IperfGetCurrentTime( &currTime, 0 );
|
||
|
udpHdr->sec = htonl( currTime );
|
||
|
udpHdr->uSec = htonl( currTime * 1000 );
|
||
|
|
||
|
nBytes = send( sockfd, buffer, dataSize, 0 );
|
||
|
|
||
|
//TODO: receive the report from server side and print out
|
||
|
|
||
|
close( sockfd );
|
||
|
freeEc( buffer );
|
||
|
bIperfCltTerminRunning = 0;
|
||
|
iperfCLtTask = NULL;
|
||
|
bIperfCltIsGoingOn = 0;
|
||
|
|
||
|
/* before iperf task exit, should allow to enter HIB/Sleep2, and release hander */
|
||
|
pmuRet = slpManPlatVoteEnableSleep(iperfPmuHdr, SLP_SLP2_STATE);
|
||
|
OsaCheck(pmuRet == RET_TRUE, pmuRet, 0, 0);
|
||
|
|
||
|
pmuRet = slpManGivebackPlatVoteHandle(iperfPmuHdr);
|
||
|
OsaCheck(pmuRet == RET_TRUE, pmuRet, 0, 0);
|
||
|
|
||
|
ECOMM_TRACE(UNILOG_TCPIP_APP, IperfUdpRunClient_11, P_SIG, 0, "iperf udp client terminal");
|
||
|
|
||
|
osThreadExit();
|
||
|
}
|
||
|
|
||
|
IperfCount IperfCalculateResult( INT32 pktSize, IperfCount pktCount, INT32 needToConvert )
|
||
|
{
|
||
|
if ( pktSize > 0 ) {
|
||
|
pktCount.Bytes += pktSize;
|
||
|
pktCount.times++;
|
||
|
}
|
||
|
|
||
|
if ( needToConvert == 1 ) {
|
||
|
if ( pktCount.Bytes >= 1024 ) {
|
||
|
pktCount.KBytes += (pktCount.Bytes / 1024);
|
||
|
pktCount.Bytes = pktCount.Bytes % 1024;
|
||
|
}
|
||
|
|
||
|
if ( pktCount.KBytes >= 1024 ) {
|
||
|
pktCount.MBytes += (pktCount.KBytes / 1024);
|
||
|
pktCount.KBytes = pktCount.KBytes % 1024;
|
||
|
}
|
||
|
|
||
|
if ( pktCount.MBytes >= 1024 ) {
|
||
|
pktCount.GBytes += (pktCount.MBytes / 1024);
|
||
|
pktCount.MBytes = pktCount.MBytes % 1024;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return pktCount;
|
||
|
}
|
||
|
|
||
|
IperfCount IperfCalculateAddHeader( INT32 domain, INT32 protocol, IperfCount pktCount )
|
||
|
{
|
||
|
if(domain == IPERF_STREAM_DOMAIN_IP4)
|
||
|
{
|
||
|
pktCount.Bytes += 20;
|
||
|
}else if(domain == IPERF_STREAM_DOMAIN_IP6) {
|
||
|
pktCount.Bytes += 40;
|
||
|
}
|
||
|
|
||
|
if(protocol == IPERF_STREAM_PROTOCOL_UDP)
|
||
|
{
|
||
|
pktCount.Bytes += 8;
|
||
|
}else if(protocol == IPERF_STREAM_PROTOCOL_TCP) {
|
||
|
pktCount.Bytes += 20;
|
||
|
}
|
||
|
|
||
|
return pktCount;
|
||
|
}
|
||
|
|
||
|
IperfCount IperfResetCount( IperfCount pktCount )
|
||
|
{
|
||
|
pktCount.Bytes = 0;
|
||
|
pktCount.KBytes = 0;
|
||
|
pktCount.MBytes = 0;
|
||
|
pktCount.GBytes = 0;
|
||
|
pktCount.times = 0;
|
||
|
|
||
|
return pktCount;
|
||
|
}
|
||
|
|
||
|
IperfCount IperfCopyCount( IperfCount pktCount, IperfCount tmpCount )
|
||
|
{
|
||
|
|
||
|
tmpCount.Bytes = pktCount.Bytes;
|
||
|
tmpCount.KBytes = pktCount.KBytes;
|
||
|
tmpCount.MBytes = pktCount.MBytes;
|
||
|
tmpCount.GBytes = pktCount.GBytes;
|
||
|
tmpCount.times = pktCount.times;
|
||
|
|
||
|
return tmpCount;
|
||
|
}
|
||
|
|
||
|
IperfCount IperfDiffCount( IperfCount pktCount, IperfCount tmpCount )
|
||
|
{
|
||
|
/* pktCount > tmpCount */
|
||
|
tmpCount.times = pktCount.times - tmpCount.times;
|
||
|
|
||
|
if ( pktCount.Bytes >= tmpCount.Bytes ) {
|
||
|
tmpCount.Bytes = pktCount.Bytes - tmpCount.Bytes;
|
||
|
} else {
|
||
|
tmpCount.Bytes = pktCount.Bytes + 1024 - tmpCount.Bytes;
|
||
|
if ( pktCount.KBytes > 0 ) {
|
||
|
pktCount.KBytes--;
|
||
|
} else if ( pktCount.MBytes > 0 ) {
|
||
|
pktCount.MBytes--;
|
||
|
pktCount.KBytes = 1023;
|
||
|
} else if ( pktCount.GBytes > 0 ) {
|
||
|
pktCount.GBytes--;
|
||
|
pktCount.MBytes = 1023;
|
||
|
pktCount.KBytes = 1023;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if ( pktCount.KBytes >= tmpCount.KBytes ) {
|
||
|
tmpCount.KBytes = pktCount.KBytes - tmpCount.KBytes;
|
||
|
} else {
|
||
|
tmpCount.KBytes = pktCount.KBytes + 1024 - tmpCount.KBytes;
|
||
|
if ( pktCount.MBytes > 0 ) {
|
||
|
pktCount.MBytes--;
|
||
|
} else if ( pktCount.GBytes > 0 ) {
|
||
|
pktCount.GBytes--;
|
||
|
pktCount.MBytes = 1023;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if ( pktCount.MBytes >= tmpCount.MBytes ) {
|
||
|
tmpCount.MBytes = pktCount.MBytes - tmpCount.MBytes;
|
||
|
} else {
|
||
|
tmpCount.MBytes = pktCount.MBytes + 1024 - tmpCount.MBytes;
|
||
|
if ( pktCount.GBytes > 0 ) {
|
||
|
pktCount.GBytes--;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return tmpCount;
|
||
|
}
|
||
|
|
||
|
BOOL IperfInit(NmIperfReq *pIperfReq)
|
||
|
{
|
||
|
osThreadId_t xReturn = NULL;
|
||
|
osThreadAttr_t attr;
|
||
|
CHAR pcNameClient[] = "iperf_c";
|
||
|
CHAR pcNameServer[] = "iperf_s";
|
||
|
|
||
|
OsaDebugBegin(pIperfReq != PNULL, pIperfReq, 0, 0);
|
||
|
return FALSE;
|
||
|
OsaDebugEnd();
|
||
|
|
||
|
//check iperf task running status
|
||
|
if (pIperfReq->reqAct == NM_IPERF_START_CLIENT)
|
||
|
{
|
||
|
if (bIperfCltIsGoingOn)
|
||
|
{
|
||
|
ECOMM_TRACE(UNILOG_TCPIP_APP, IperfInit_1, P_WARNING, 0, "iperf client is going on,please run it wait a moment");
|
||
|
return FALSE;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
bIperfCltIsGoingOn = TRUE;
|
||
|
}
|
||
|
}
|
||
|
else if(pIperfReq->reqAct == NM_IPERF_START_SERVER || pIperfReq->reqAct == NM_IPERF_START_UDP_NAT_SERVER)
|
||
|
{
|
||
|
if (bIperfSrvIsGoingOn)
|
||
|
{
|
||
|
ECOMM_TRACE(UNILOG_TCPIP_APP, IperfInit_2, P_WARNING, 0, "iperf server is going on,please run it wait a moment");
|
||
|
return FALSE;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
bIperfSrvIsGoingOn = TRUE;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
ECOMM_TRACE(UNILOG_TCPIP_APP, IperfInit_3, P_WARNING, 0, "iperf mode is invalid");
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
//set task attr
|
||
|
memset(&attr, 0, sizeof(osThreadAttr_t));
|
||
|
attr.name = ((pIperfReq->reqAct == NM_IPERF_START_CLIENT) ? pcNameClient : pcNameServer);
|
||
|
attr.stack_size = IPERF_THREAD_STACKSIZE;
|
||
|
attr.priority = (osPriority_t)IPERF_THREAD_PRIO;
|
||
|
|
||
|
#ifdef TYPE_EC718M
|
||
|
attr.reserved = osThreadDynamicStackAlloc;
|
||
|
#endif
|
||
|
|
||
|
//setup iperf task
|
||
|
if(pIperfReq->reqAct == NM_IPERF_START_CLIENT)
|
||
|
{
|
||
|
memcpy(&pIperfClientReq, pIperfReq, sizeof(NmIperfReq));
|
||
|
|
||
|
if (pIperfReq->protocol == NM_IPERF_PROTOCOL_UDP)
|
||
|
{ //udp
|
||
|
xReturn = osThreadNew(IperfUdpRunClient, (void*)&pIperfClientReq, &attr);
|
||
|
}
|
||
|
else if (pIperfReq->protocol == NM_IPERF_PROTOCOL_TCP)
|
||
|
{ //tcp
|
||
|
xReturn = osThreadNew(IperfTcpRunClient, (void*)&pIperfClientReq, &attr);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
ECOMM_TRACE(UNILOG_TCPIP_APP, IperfInit_4, P_WARNING, 0, "iperf protocol is invalid");
|
||
|
bIperfCltIsGoingOn = FALSE;
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
if (xReturn == NULL)
|
||
|
{
|
||
|
ECOMM_TRACE(UNILOG_TCPIP_APP, IperfInit_5, P_WARNING, 0, "can not create iperf task");
|
||
|
bIperfCltIsGoingOn = FALSE;
|
||
|
return FALSE;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
iperfCLtTask = xReturn;
|
||
|
}
|
||
|
}
|
||
|
else if(pIperfReq->reqAct == NM_IPERF_START_SERVER)
|
||
|
{
|
||
|
memcpy(&pIperfServerReq, pIperfReq, sizeof(NmIperfReq));
|
||
|
|
||
|
if (pIperfReq->protocol == NM_IPERF_PROTOCOL_UDP)
|
||
|
{ //udp
|
||
|
xReturn = osThreadNew(IperfUdpRunServer, (void*)&pIperfServerReq, &attr);
|
||
|
}
|
||
|
else if (pIperfReq->protocol == NM_IPERF_PROTOCOL_TCP)
|
||
|
{ //tcp
|
||
|
xReturn = osThreadNew(IperfTcpRunServer, (void*)&pIperfServerReq, &attr);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
ECOMM_TRACE(UNILOG_TCPIP_APP, IperfInit_6, P_WARNING, 0, "iperf protocol is invalid");
|
||
|
bIperfSrvIsGoingOn = FALSE;
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
if (xReturn == NULL)
|
||
|
{
|
||
|
ECOMM_TRACE(UNILOG_TCPIP_APP, IperfInit_7, P_WARNING, 0, "can not create iperf task");
|
||
|
bIperfSrvIsGoingOn = FALSE;
|
||
|
return FALSE;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
iperfSrvTask = xReturn;
|
||
|
}
|
||
|
}
|
||
|
else if(pIperfReq->reqAct == NM_IPERF_START_UDP_NAT_SERVER)
|
||
|
{
|
||
|
memcpy(&pIperfServerReq, pIperfReq, sizeof(NmIperfReq));
|
||
|
|
||
|
if (pIperfReq->protocol == IPERF_STREAM_PROTOCOL_UDP)
|
||
|
{ //udp
|
||
|
xReturn = osThreadNew(IperfUdpRunNatServer, (void*)&pIperfServerReq, &attr);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
ECOMM_TRACE(UNILOG_TCPIP_APP, IperfInit_6, P_WARNING, 0, "iperf protocol is invalid");
|
||
|
bIperfSrvIsGoingOn = FALSE;
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
if (xReturn == NULL)
|
||
|
{
|
||
|
ECOMM_TRACE(UNILOG_TCPIP_APP, IperfInit_7, P_WARNING, 0, "can not create iperf task");
|
||
|
bIperfSrvIsGoingOn = FALSE;
|
||
|
return FALSE;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
iperfSrvTask = xReturn;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
|
||
|
void IperfTerminate(NmIperfReq *pIperfReq)
|
||
|
{
|
||
|
OsaDebugBegin(pIperfReq != PNULL, pIperfReq, 0, 0);
|
||
|
return;
|
||
|
OsaDebugEnd();
|
||
|
|
||
|
switch(pIperfReq->reqAct)
|
||
|
{
|
||
|
case NM_IPERF_STOP_ALL:
|
||
|
{
|
||
|
if(iperfCLtTask)
|
||
|
{
|
||
|
bIperfCltTerminRunning = 1;
|
||
|
}
|
||
|
if(iperfSrvTask)
|
||
|
{
|
||
|
bIperfSrvTerminRunning = 1;
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
case NM_IPERF_STOP_CLIENT:
|
||
|
{
|
||
|
if(iperfCLtTask)
|
||
|
{
|
||
|
bIperfCltTerminRunning = 1;
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
case NM_IPERF_STOP_SERVER:
|
||
|
{
|
||
|
if(iperfSrvTask)
|
||
|
{
|
||
|
bIperfSrvTerminRunning = 1;
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
|