| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984 |
- /*
- A FreeRTOS+TCP demo program:
- A simple example of a TCP/UDP iperf server, see https://iperf.fr
- It uses a single task which will store some client information in a:
- List_t xTCPClientList;
- The task will sleep constantly by calling:
- xResult = FreeRTOS_select( xSocketSet, xBlockingTime );
- Command examples for testing:
- iperf3 -c 192.168.2.114 --port 5001 --bytes 100M
- iperf3 -c 192.168.2.114 --port 5001 --bytes 100M -R
- iperf3 -c fe80::8d11:cd9b:8b66:4a80 --port 5001 --bytes 1M
- iperf3 -c fe80::8d11:cd9b:8b66:4a81 --port 5001 --bytes 1M
- iperf3 -c fe80::6802:9887:8670:b37c --port 5001 --bytes 1M
-
- ping fe80::8d11:cd9b:8b66:4a80
- ping fe80::8d11:cd9b:8b66:4a81
- iperf3 -s --port 5001
- iperf3 -c zynq --port 5001 --bytes 1024
- iperf3 -c laptop --port 5001 --bytes 1024
- fe80::8d11:cd9b:8b66:4a80
- TCP : iperf3 -c 192.168.2.116 --port 5001 --bytes 1024
- UDP : iperf3 -c 192.168.2.116 --port 5001 --udp --bandwidth 50M --mss 1460 --bytes 1024
- */
- /* Standard includes. */
- #include <stdio.h>
- #include <time.h>
- /* FreeRTOS includes. */
- #include <FreeRTOS.h>
- #include "task.h"
- #include "timers.h"
- /* FreeRTOS+TCP includes. */
- #include "FreeRTOS_IP.h"
- #include "FreeRTOS_Sockets.h"
- #include "FreeRTOS_TCP_IP.h"
- #include "iperf_task.h"
- /* Put the TCP server at this port number: */
- #ifndef ipconfigIPERF_TCP_ECHO_PORT
- /* 5001 seems to be the standard TCP server port number. */
- #define ipconfigIPERF_TCP_ECHO_PORT 5001
- #endif
- /* Put the TCP server at this port number: */
- #ifndef ipconfigIPERF_UDP_ECHO_PORT
- /* 5001 seems to be the standard UDP server port number. */
- #define ipconfigIPERF_UDP_ECHO_PORT 5001
- #endif
- #ifndef ipconfigIPERF_STACK_SIZE_IPERF_TASK
- /* Stack size needed for vIPerfTask(), a bit of a guess: */
- #define ipconfigIPERF_STACK_SIZE_IPERF_TASK 340
- #endif
- #ifndef ipconfigIPERF_PRIORITY_IPERF_TASK
- /* The priority of vIPerfTask(). Should be lower than the IP-task
- and the task running in NetworkInterface.c. */
- #define ipconfigIPERF_PRIORITY_IPERF_TASK 3
- #endif
- #ifndef ipconfigIPERF_RECV_BUFFER_SIZE
- /* Only used when ipconfigIPERF_USE_ZERO_COPY = 0.
- Buffer size when reading from the sockets. */
- #define ipconfigIPERF_RECV_BUFFER_SIZE ( 4 * ipconfigTCP_MSS )
- #endif
- #ifndef ipconfigIPERF_LOOP_BLOCKING_TIME_MS
- /* Let the mainloop wake-up so now and then. */
- #define ipconfigIPERF_LOOP_BLOCKING_TIME_MS 5000UL
- #endif
- #ifndef ipconfigIPERF_HAS_TCP
- /* A TCP server socket will be created. */
- #define ipconfigIPERF_HAS_TCP 1
- #endif
- #ifndef ipconfigIPERF_HAS_UDP
- /* A UDP server socket will be created. */
- #define ipconfigIPERF_HAS_UDP 1
- #endif
- #ifndef ipconfigIPERF_DOES_ECHO_UDP
- /* By default, this server will echo UDP data as required by iperf. */
- #define ipconfigIPERF_DOES_ECHO_UDP 1
- #endif
- #ifndef ipconfigIPERF_USE_ZERO_COPY
- #define ipconfigIPERF_USE_ZERO_COPY 1
- #endif
- #ifndef ipconfigIPERF_TX_BUFSIZE
- #define ipconfigIPERF_TX_BUFSIZE ( 65 * 1024 ) /* Units of bytes. */
- #define ipconfigIPERF_TX_WINSIZE ( 4 ) /* Size in units of MSS */
- #define ipconfigIPERF_RX_BUFSIZE ( ( 65 * 1024 ) - 1 ) /* Units of bytes. */
- #define ipconfigIPERF_RX_WINSIZE ( 8 ) /* Size in units of MSS */
- #endif
- #ifndef ARRAY_SIZE
- #define ARRAY_SIZE(x) (BaseType_t)(sizeof(x)/sizeof(x)[0])
- #endif
- void vIPerfTask( void *pvParameter );
- /* As for now, still defined in 'FreeRTOS-Plus-TCP\FreeRTOS_TCP_WIN.c' : */
- extern void vListInsertGeneric( List_t * const pxList, ListItem_t * const pxNewListItem, MiniListItem_t * const pxWhere );
- static portINLINE void vListInsertFifo( List_t * const pxList, ListItem_t * const pxNewListItem )
- {
- vListInsertGeneric( pxList, pxNewListItem, &pxList->xListEnd );
- }
- #if( ipconfigIPERF_VERSION == 3 )
- typedef enum
- {
- eTCP_0_WaitName, /* Expect a text like "osboxes.1460335312.612572.527642c36f" */
- eTCP_1_WaitCount,
- eTCP_2_WaitHeader,
- eTCP_3_WaitOneTwo,
- eTCP_4_WaitCount2,
- eTCP_5_WaitHeader2,
- eTCP_6_WaitDone,
- eTCP_7_WaitTransfer
- } eTCP_Server_Status_t;
- #endif
- typedef struct
- {
- Socket_t xServerSocket;
- #if( ipconfigIPERF_VERSION == 3 )
- struct {
- uint32_t
- bIsControl : 1,
- bReverse : 1,
- bTimed : 1, /* Reverse role, limited time. */
- bTimedOut : 1, /* TIme is up. */
- bHasShutdown : 1;
- } bits;
- eTCP_Server_Status_t eTCP_Status;
- uint32_t ulSkipCount, ulAmount;
- uint32_t xRemainingTime;
- TimeOut_t xTimeOut;
- #endif /* ipconfigIPERF_VERSION == 3 */
- #if( ipconfigUSE_IPv6 != 0 )
- struct freertos_sockaddr6 xRemoteAddr;
- #else
- struct freertos_sockaddr xRemoteAddr;
- #endif
- uint32_t ulRecvCount;
- struct xLIST_ITEM xListItem; /* With this item the client will be bound to a List_t. */
- } TcpClient_t;
- #if( ipconfigIPERF_USE_ZERO_COPY != 0 )
- struct xRawBuffer {
- char pcBuffer[ ipconfigIPERF_RECV_BUFFER_SIZE ];
- } *pxRawBuffer;
- #define pcSendBuffer ( pxRawBuffer->pcBuffer )
- static char *pcRecvBuffer;
- #else
- struct xRawBuffer {
- char pcBuffer[ ipconfigIPERF_RECV_BUFFER_SIZE ];
- } *pxRawBuffer;
- #define pcRecvBuffer ( pxRawBuffer->pcBuffer )
- #define pcSendBuffer ( pxRawBuffer->pcBuffer )
- #endif
- #if( ipconfigIPERF_VERSION == 3 )
- char pcExpectedClient[ 80 ];
- TcpClient_t *pxControlClient, *pxDataClient;
- /*{"cpu_util_total":0,"cpu_util_user":0,"cpu_util_system":0,"sender_has_retransmits":-1,"streams":[{"id":1,"bytes":8760,"retransmits":-1,"jitter":0,"errors":0,"packets":0}]} */
- #endif
- static List_t xTCPClientList;
- #if( ipconfigIPERF_HAS_UDP != 0 )
- static uint32_t ulUDPRecvCount = 0, ulUDPRecvCountShown = 0, ulUDPRecvCountSeen = 0;
- #endif
- static SocketSet_t xSocketSet;
- static TaskHandle_t pxIperfTask;
- void vIPerfInstall( void )
- {
- if( pxRawBuffer == NULL )
- {
- pxRawBuffer = ( struct xRawBuffer * ) pvPortMalloc( sizeof *pxRawBuffer );
- if( pxRawBuffer == NULL )
- {
- FreeRTOS_printf( ( "vIPerfInstall: malloc %u bytes failed.\n", (unsigned)sizeof *pxRawBuffer ) ) ;
- return;
- }
- }
- if( pxIperfTask == NULL )
- {printf("start iperf\r\n");
- /* Call this function once to start the test with FreeRTOS_accept(). */
- xTaskCreate( vIPerfTask, "IPerf", ipconfigIPERF_STACK_SIZE_IPERF_TASK, NULL, ipconfigIPERF_PRIORITY_IPERF_TASK, &pxIperfTask );
- }
- }
- static void vIPerfServerWork( Socket_t xSocket )
- {
- struct freertos_sockaddr xAddress;
- socklen_t xSocketLength;
- Socket_t xNexSocket;
- xNexSocket = FreeRTOS_accept( xSocket, &xAddress, &xSocketLength);
- if( ( xNexSocket != NULL ) && ( xNexSocket != FREERTOS_INVALID_SOCKET ) )
- {
- char pucBuffer[ 16 ];
- TcpClient_t *pxClient;
-
- pxClient = ( TcpClient_t * )pvPortMalloc( sizeof *pxClient );
- memset( pxClient, '\0', sizeof *pxClient );
- pxClient->xServerSocket = xNexSocket;
- listSET_LIST_ITEM_OWNER( &( pxClient->xListItem ), ( void* ) pxClient );
- #if( ipconfigUSE_IPv6 != 0 )
- FreeRTOS_GetRemoteAddress( xNexSocket, ( struct freertos_sockaddr6 * ) &pxClient->xRemoteAddr );
- #else
- FreeRTOS_GetRemoteAddress( xNexSocket, ( struct freertos_sockaddr * ) &pxClient->xRemoteAddr );
- FreeRTOS_inet_ntoa( pxClient->xRemoteAddr.sin_addr, pucBuffer );
- FreeRTOS_printf( ( "vIPerfTask: Received a connection from %s:%u\n",
- pucBuffer,
- FreeRTOS_ntohs( pxClient->xRemoteAddr.sin_port ) ) );
- #endif
- FreeRTOS_FD_SET( xNexSocket, xSocketSet, eSELECT_READ );
- vListInsertFifo( &xTCPClientList, &( pxClient->xListItem ) );
- }
- }
- static void vIPerfTCPClose( TcpClient_t *pxClient )
- {
- if( pxControlClient == pxClient )
- {
- pxControlClient = NULL;
- }
- if( pxDataClient == pxClient )
- {
- pxDataClient = NULL;
- }
- /* Remove server socket from the socket set. */
- if( pxClient->xServerSocket != NULL )
- {
- char pucBuffer[ 16 ];
- #if( ipconfigUSE_IPv6 == 0 )
- FreeRTOS_inet_ntoa( pxClient->xRemoteAddr.sin_addr, pucBuffer );
- FreeRTOS_printf( ( "vIPerfTCPClose: Closing server socket %s:%u after %lu bytes\n",
- pucBuffer,
- FreeRTOS_ntohs( pxClient->xRemoteAddr.sin_port ),
- pxClient->ulRecvCount ) );
- #endif
- FreeRTOS_FD_CLR( pxClient->xServerSocket, xSocketSet, eSELECT_ALL );
- FreeRTOS_closesocket( pxClient->xServerSocket );
- pxClient->xServerSocket = NULL;
- }
- /* Remove client socket from the socket set. */
- {
- if( pxClient->xServerSocket == NULL )
- {
- /* Remove this socket from the list. */
- uxListRemove( &( pxClient->xListItem ) );
- vPortFree( ( void * ) pxClient );
- }
- }
- }
- static int vIPerfTCPSend( TcpClient_t *pxClient )
- {
- BaseType_t xResult = 0;
- do
- {
- size_t uxMaxSpace = (size_t) FreeRTOS_tx_space( pxClient->xServerSocket );
- size_t uxSize = (size_t)FreeRTOS_min_uint32( uxMaxSpace, ( int32_t )sizeof( pcSendBuffer ) );
- if( pxClient->bits.bTimed != pdFALSE_UNSIGNED )
- {
- if( xTaskCheckForTimeOut( &( pxClient->xTimeOut ), &( pxClient->xRemainingTime ) ) != pdFALSE )
- {
- /* Time is up. */
- if( pxClient->bits.bTimedOut == pdFALSE_UNSIGNED )
- {
- FreeRTOS_shutdown( pxClient->xServerSocket, FREERTOS_SHUT_RDWR );
- pxClient->bits.bTimedOut = pdTRUE_UNSIGNED;
- }
- break;
- }
- }
- uxSize = FreeRTOS_min_uint32( uxSize, pxClient->ulAmount );
- if( uxSize <= 0 )
- {
- break;
- }
- xResult = FreeRTOS_send( pxClient->xServerSocket, (const void *)pcSendBuffer, uxSize, 0 );
- if( xResult < 0 )
- {
- break;
- }
- if( pxClient->bits.bTimed == pdFALSE_UNSIGNED )
- {
- pxClient->ulAmount -= uxSize;
- if( pxClient->ulAmount == 0ul )
- {
- /* All data have been sent. No longer interested in eSELECT_WRITE events. */
- FreeRTOS_FD_CLR( pxClient->xServerSocket, xSocketSet, eSELECT_WRITE );
- }
- }
- if( uxSize > 0 )
- {
- xResult += uxSize;
- }
- }
- while( 0 );
- return xResult;
- }
- #if( ipconfigIPERF_VERSION == 3 )
- static void handleRecvPacket( TcpClient_t *pxClient, char *pcReadBuffer, BaseType_t xRecvResult )
- {
- BaseType_t xRemaining = xRecvResult;
- if( pxClient->eTCP_Status < eTCP_7_WaitTransfer )
- {
- FreeRTOS_printf( ( "TCP[ port %d ] recv[ %d ] %d\n", FreeRTOS_ntohs( pxClient->xRemoteAddr.sin_port ), ( int ) pxClient->eTCP_Status, ( int )xRecvResult ) );
- }
- /*
- 2016-04-11 09:26:55.533 192.168.2.106 16.926.349 [] TCP recv[ 1 ] 4
- 2016-04-11 09:26:55.539 192.168.2.106 16.926.365 [] TCP skipcount 83 xRecvResult 4
- 2016-04-11 09:26:55.546 192.168.2.106 16.926.402 [] TCP recv[ 2 ] 4
- 2016-04-11 09:26:55.552 192.168.2.106 16.927.015 [] ipTCP_FLAG_PSH received
- 2016-04-11 09:26:55.560 192.168.2.106 16.927.085 [] TCP recv[ 2 ] 83
- */
- switch( pxClient->eTCP_Status )
- {
- case eTCP_0_WaitName:
- {
- int rc;
- if( pcExpectedClient[ 0 ] != '\0' )
- {
- /* Get a string like 'LAPTOP.1463928623.162445.0fbe105c6eb',
- where 'LAPTOP' is the hostname. */
- rc = strncmp( pcExpectedClient, pcReadBuffer, sizeof( pcExpectedClient ) );
- }
- else
- {
- rc = -1;
- }
- {
- unsigned char tab[ 1 ] = { '\t' };
- FreeRTOS_send( pxClient->xServerSocket, (const void *)tab, 1, 0 );
- }
- if( rc != 0 )
- {
- FreeRTOS_printf( ( "Got Control Socket: rc %d: exp: '%s' got: '%s'\n", rc, pcExpectedClient, pcReadBuffer ) );
- strncpy( pcExpectedClient, pcReadBuffer, sizeof( pcExpectedClient ) );
- pxControlClient = pxClient;
- pxClient->bits.bIsControl = pdTRUE_UNSIGNED;
- pxClient->eTCP_Status = ( eTCP_Server_Status_t ) ( ( ( int ) pxClient->eTCP_Status ) + 1 );
- }
- else
- {
- FreeRTOS_printf( ( "Got expected client: rc %d: '%s'\n", rc, pcExpectedClient ) );
- pcExpectedClient[ 0 ] = '\0';
- pxDataClient = pxClient;
- if( pxControlClient != NULL )
- {
- /* Transfer all properties to the data client. */
- memcpy( &( pxDataClient->bits ), &( pxControlClient->bits ), sizeof( pxDataClient->bits ) );
- pxDataClient->ulAmount = pxControlClient->ulAmount;
- pxDataClient->xRemainingTime = pxControlClient->xRemainingTime;
- vTaskSetTimeOutState( &( pxDataClient->xTimeOut ) );
- if( pxDataClient->bits.bReverse != pdFALSE_UNSIGNED )
- {
- /* As this socket will only write data, set the WRITE select flag. */
- FreeRTOS_FD_SET( pxClient->xServerSocket, xSocketSet, eSELECT_WRITE );
- }
- pxControlClient->bits.bIsControl = pdTRUE_UNSIGNED;
- pxDataClient->bits.bIsControl = pdFALSE_UNSIGNED;
- }
- pxDataClient->eTCP_Status = eTCP_7_WaitTransfer;
- }
- }
- break;
- case eTCP_1_WaitCount:
- if( xRemaining < 4 )
- {
- break;
- }
- {
- pxClient->ulSkipCount =
- ( ( ( uint32_t ) pcReadBuffer[ 0 ] ) << 24 ) |
- ( ( ( uint32_t ) pcReadBuffer[ 1 ] ) << 16 ) |
- ( ( ( uint32_t ) pcReadBuffer[ 2 ] ) << 8 ) |
- ( ( ( uint32_t ) pcReadBuffer[ 3 ] ) << 0 );
- /* Receive a number: an amount of bytes to be skipped. */
- FreeRTOS_printf( ( "TCP skipcount %u xRecvResult %d\n", ( unsigned )pxClient->ulSkipCount, ( int )xRemaining ) );
- pcReadBuffer += 4;
- xRemaining -= 4;
- pxClient->eTCP_Status = ( eTCP_Server_Status_t ) ( ( ( int ) pxClient->eTCP_Status ) + 1 );
- }
- if( xRemaining == 0 )
- {
- break;
- }
- /* fall through */
- case eTCP_2_WaitHeader:
- {
- if (xRemaining > 0) {
- char *pcPtr;
- pcReadBuffer[ xRemaining ] = '\0';
- FreeRTOS_printf( ( "Control string: %s\n", pcReadBuffer ) );
- for( pcPtr = pcReadBuffer; *pcPtr; pcPtr++ )
- {
- if( strncmp( pcPtr, "\"reverse\"", 9 ) == 0 )
- {
- pxClient->bits.bReverse = pcPtr[ 10 ] == 't';
- }
- else if( strncmp( pcPtr, "\"num\"", 5 ) == 0 )
- {
- uint32_t ulAmount;
- if( sscanf( pcPtr + 6, "%lu", &( ulAmount ) ) > 0 )
- {
- pxClient->ulAmount = ulAmount;
- }
- }
- else if( strncmp( pcPtr, "\"time\"", 6 ) == 0 )
- {
- uint32_t ulSeconds;
- if( sscanf( pcPtr + 7, "%lu", &( ulSeconds ) ) > 0 )
- {
- pxClient->xRemainingTime = ulSeconds * 1000ul;
- pxClient->bits.bTimed = pdTRUE_UNSIGNED;
- }
- }
- }
- if( pxClient->bits.bReverse != pdFALSE_UNSIGNED )
- {
- FreeRTOS_printf( ( "Reverse %d send %lu bytes timed %d: %lu\n",
- pxClient->bits.bReverse, pxClient->ulAmount,
- pxClient->bits.bTimed,
- pxClient->xRemainingTime ) );
- }
- }
- if( pxClient->ulSkipCount > ( uint32_t ) xRemaining )
- {
- pxClient->ulSkipCount -= ( uint32_t ) xRemaining;
- }
- else
- {
- unsigned char newline[ 1 ] = { '\n' };
- unsigned char onetwo[ 2 ] = { '\1', '\2' };
- FreeRTOS_send( pxClient->xServerSocket, (const void *)newline, sizeof( newline ), 0 );
- FreeRTOS_send( pxClient->xServerSocket, (const void *)onetwo, sizeof( onetwo ), 0 );
- pxClient->ulSkipCount = 0;
- pxClient->eTCP_Status = ( eTCP_Server_Status_t ) ( ( ( int ) pxClient->eTCP_Status ) + 1 );
- }
- }
- break;
- case eTCP_3_WaitOneTwo:
- {
- unsigned char ch = pcReadBuffer[ 0 ];
- unsigned char cr[ 1 ] = { '\r' };
- FreeRTOS_printf( ( "TCP[ port %d ] recv %d bytes: 0x%02X\n",
- FreeRTOS_ntohs( pxClient->xRemoteAddr.sin_port ), ( int )xRecvResult, ch ) );
- ch = ch;
- FreeRTOS_send( pxClient->xServerSocket, (const void *)cr, sizeof( cr ), 0 );
- pxClient->eTCP_Status = ( eTCP_Server_Status_t ) ( ( ( int ) pxClient->eTCP_Status ) + 1 );
- }
- break;
- case eTCP_4_WaitCount2:
- if( xRemaining < 4 )
- {
- break;
- }
- {
- pxClient->ulSkipCount =
- ( ( ( uint32_t ) pcReadBuffer[ 0 ] ) << 24 ) |
- ( ( ( uint32_t ) pcReadBuffer[ 1 ] ) << 16 ) |
- ( ( ( uint32_t ) pcReadBuffer[ 2 ] ) << 8 ) |
- ( ( ( uint32_t ) pcReadBuffer[ 3 ] ) << 0 );
- FreeRTOS_printf( ( "TCP skipcount %lu xRecvResult %ld\n", pxClient->ulSkipCount, xRemaining ) );
- pcReadBuffer += 4;
- xRemaining -= 4;
- pxClient->eTCP_Status = ( eTCP_Server_Status_t ) ( ( ( int ) pxClient->eTCP_Status ) + 1 );
- }
- if( xRemaining == 0 )
- {
- break;
- }
- /* fall through */
- case eTCP_5_WaitHeader2:
- {
- if( pxClient->ulSkipCount > ( uint32_t ) xRemaining )
- {
- pxClient->ulSkipCount -= xRemaining;
- }
- else
- {
- char pcResponse[ 200 ];
- uint32_t ulLength, ulStore, ulCount = 0;
- if( pxDataClient != NULL )
- {
- ulCount = pxDataClient->ulRecvCount;
- }
- ulLength = snprintf( pcResponse + 4, sizeof( pcResponse ) - 4,
- "{"
- "\"cpu_util_total\":0,"
- "\"cpu_util_user\":0,"
- "\"cpu_util_system\":0,"
- "\"sender_has_retransmits\":-1,"
- "\"streams\":["
- "{"
- "\"id\":1,"
- "\"bytes\":%lu,"
- "\"retransmits\":-1,"
- "\"jitter\":0,"
- "\"errors\":0,"
- "\"packets\":0"
- "}"
- "]"
- "}\xe",
- ulCount );
- ulStore = FreeRTOS_htonl( ulLength - 1 );
- memcpy( pcResponse, &( ulStore ), sizeof ( ulStore ) );
- FreeRTOS_send( pxClient->xServerSocket, (const void *)pcResponse, ulLength + 4, 0 );
- pxClient->ulSkipCount = 0;
- pxClient->eTCP_Status = ( eTCP_Server_Status_t ) ( ( ( int ) pxClient->eTCP_Status ) + 1 );
- }
- }
- break;
- case eTCP_6_WaitDone:
- break;
- case eTCP_7_WaitTransfer:
- break;
- }
- }
- #endif /* ipconfigIPERF_VERSION == 3 */
- static void vIPerfTCPWork( TcpClient_t *pxClient )
- {
- BaseType_t xRecvResult;
- //#warning take away
- //BaseType_t xLogged = pdFALSE;
- if( pxClient->xServerSocket == NULL )
- {
- vIPerfTCPClose( pxClient );
- return;
- }
- #if( ipconfigIPERF_VERSION == 3 )
- /* Is this a data client with the -R reverse option ? */
- if( ( pxClient->bits.bIsControl == pdFALSE_UNSIGNED ) && ( pxClient->bits.bReverse != pdFALSE_UNSIGNED ) )
- {
- if( ( pxClient->bits.bTimed == pdFALSE_UNSIGNED ) && ( pxClient->bits.bHasShutdown == pdFALSE_UNSIGNED ) && ( pxClient->ulAmount == (uint32_t)0u ) )
- {
- FreeRTOS_printf( ( "Shutdown connection\n" ) );
- FreeRTOS_shutdown( pxClient->xServerSocket, FREERTOS_SHUT_RDWR );
- pxClient->bits.bHasShutdown = pdTRUE_UNSIGNED;
- }
- }
- #endif
- for( ;; )
- {
- #if( ipconfigIPERF_USE_ZERO_COPY != 0 )
- {
- const BaseType_t xRecvSize = 0x10000;
- xRecvResult = FreeRTOS_recv( pxClient->xServerSocket, /* The socket being received from. */
- &pcRecvBuffer, /* The buffer into which the received data will be written. */
- xRecvSize, /* Any size is OK here. */
- FREERTOS_ZERO_COPY );
- }
- #else
- {
- const BaseType_t xRecvSize = sizeof pcRecvBuffer;
- xRecvResult = FreeRTOS_recv( pxClient->xServerSocket, /* The socket being received from. */
- pcRecvBuffer, /* The buffer into which the received data will be written. */
- sizeof pcRecvBuffer, /* The size of the buffer provided to receive the data. */
- 0 );
- }
- #endif
- if( xRecvResult <= 0 )
- {
- break;
- }
- pxClient->ulRecvCount += xRecvResult;
- #if( ipconfigIPERF_VERSION == 3 )
- if( pxClient->eTCP_Status < eTCP_6_WaitDone )
- {
- handleRecvPacket(pxClient, pcRecvBuffer, xRecvResult);
- }
- #endif /* ipconfigIPERF_VERSION == 3 */
- #if( ipconfigIPERF_USE_ZERO_COPY != 0 )
- {
- FreeRTOS_recv( pxClient->xServerSocket, /* The socket being received from. */
- NULL, /* The buffer into which the received data will be written. */
- xRecvResult, /* This is important now. */
- 0 );
- }
- #endif
- } /* for( ;; ) */
- if( ( xRecvResult == 0 ) && ( pxClient->bits.bIsControl == pdFALSE_UNSIGNED ) && ( pxClient->bits.bReverse != pdFALSE_UNSIGNED ) )
- {
- xRecvResult = vIPerfTCPSend( pxClient );
- }
- if( ( xRecvResult < 0 ) && ( xRecvResult != -pdFREERTOS_ERRNO_EAGAIN ) )
- {
- vIPerfTCPClose( pxClient );
- }
- }
- #if( ipconfigUSE_CALLBACKS == 0 ) && ( ipconfigIPERF_HAS_UDP != 0 )
- static void vIPerfUDPWork( Socket_t xSocket )
- {
- BaseType_t xRecvResult;
- struct freertos_sockaddr xAddress;
- uint32_t xAddressLength;
- #if( ipconfigIPERF_USE_ZERO_COPY != 0 )
- {
- xRecvResult = FreeRTOS_recvfrom( xSocket, ( void * ) &pcRecvBuffer, sizeof( pcRecvBuffer ),
- FREERTOS_ZERO_COPY, &xAddress, &xAddressLength );
- }
- #else
- {
- xRecvResult = FreeRTOS_recvfrom( xSocket, ( void * ) pcRecvBuffer, sizeof( pcRecvBuffer ),
- 0, &xAddress, &xAddressLength );
- }
- #endif /* ipconfigIPERF_USE_ZERO_COPY */
- if( xRecvResult > 0 )
- {
- ulUDPRecvCount += xRecvResult;
- #if( ipconfigIPERF_DOES_ECHO_UDP != 0 )
- {
- FreeRTOS_sendto( xSocket, (const void *)pcRecvBuffer, xRecvResult, 0, &xAddress, sizeof( xAddress ) );
- }
- #endif /* ipconfigIPERF_DOES_ECHO_UDP */
- #if( ipconfigIPERF_USE_ZERO_COPY != 0 )
- {
- FreeRTOS_ReleaseUDPPayloadBuffer( pcRecvBuffer );
- }
- #endif /* ipconfigIPERF_USE_ZERO_COPY */
- }
- }
- #endif /* ipconfigUSE_CALLBACKS == 0 */
- #if( ipconfigUSE_CALLBACKS != 0 ) && ( ipconfigIPERF_HAS_UDP != 0 )
- static BaseType_t xOnUdpReceive( Socket_t xSocket, void * pvData, size_t xLength,
- const struct freertos_sockaddr *pxFrom, const struct freertos_sockaddr *pxDest )
- {
- ( void ) pvData;
- ( void ) pxFrom;
- ulUDPRecvCount += xLength;
- #if( ipconfigIPERF_DOES_ECHO_UDP != 0 )
- {
- FreeRTOS_sendto( xSocket, (const void *)pcRecvBuffer, xLength, 0, pxFrom, sizeof( *pxFrom ) );
- }
- #else /* ipconfigIPERF_DOES_ECHO_UDP */
- {
- ( void ) xSocket;
- }
- #endif
- /* Tell the driver not to store the RX data */
- return 1;
- }
- #endif /* ipconfigUSE_CALLBACKS != 0 */
- #if( ipconfigIPERF_HAS_TCP != 0 )
- static Socket_t xCreateTCPServerSocket()
- {
- BaseType_t xBindResult, xListenResult;
- struct freertos_sockaddr xEchoServerAddress;
- Socket_t xTCPServerSocket;
- TickType_t xNoTimeOut = 0;
- xTCPServerSocket = FreeRTOS_socket( FREERTOS_AF_INET, FREERTOS_SOCK_STREAM, FREERTOS_IPPROTO_TCP );
- configASSERT( ( xTCPServerSocket != FREERTOS_INVALID_SOCKET ) && ( xTCPServerSocket != NULL ) );
- memset( &xEchoServerAddress, '\0', sizeof xEchoServerAddress );
- xEchoServerAddress.sin_port = FreeRTOS_htons( ipconfigIPERF_TCP_ECHO_PORT );
- /* Set the receive time out to portMAX_DELAY.
- Note that any TCP child connections will inherit this reception time-out. */
- FreeRTOS_setsockopt( xTCPServerSocket, 0, FREERTOS_SO_RCVTIMEO, &xNoTimeOut, sizeof( xNoTimeOut ) );
- {
- WinProperties_t xWinProperties;
- memset(&xWinProperties, '\0', sizeof xWinProperties);
- xWinProperties.lTxBufSize = ipconfigIPERF_TX_BUFSIZE; /* Units of bytes. */
- xWinProperties.lTxWinSize = ipconfigIPERF_TX_WINSIZE; /* Size in units of MSS */
- xWinProperties.lRxBufSize = ipconfigIPERF_RX_BUFSIZE; /* Units of bytes. */
- xWinProperties.lRxWinSize = ipconfigIPERF_RX_WINSIZE; /* Size in units of MSS */
- FreeRTOS_setsockopt( xTCPServerSocket, 0, FREERTOS_SO_WIN_PROPERTIES, ( void * ) &xWinProperties, sizeof( xWinProperties ) );
- }
- xBindResult = FreeRTOS_bind( xTCPServerSocket, &xEchoServerAddress, sizeof xEchoServerAddress );
- xListenResult = FreeRTOS_listen( xTCPServerSocket, 4 );
- FreeRTOS_FD_SET( xTCPServerSocket, xSocketSet, eSELECT_READ );
- FreeRTOS_printf( ( "vIPerfTask: created TCP server socket %p bind port %u: %ld listen %ld\n",
- xTCPServerSocket, ipconfigIPERF_TCP_ECHO_PORT, xBindResult, xListenResult ) );
- xBindResult = xBindResult;
- xListenResult = xListenResult;
- return xTCPServerSocket;
- }
- #endif /* ipconfigIPERF_HAS_TCP */
- #if( ipconfigIPERF_HAS_UDP != 0 )
- static Socket_t xCreateUDPServerSocket()
- {
- BaseType_t xBindResult;
- struct freertos_sockaddr xEchoServerAddress;
- TickType_t xNoTimeOut = 0;
- Socket_t xUDPServerSocket;
- xUDPServerSocket = FreeRTOS_socket( FREERTOS_AF_INET, FREERTOS_SOCK_DGRAM, FREERTOS_IPPROTO_UDP );
- configASSERT( ( xUDPServerSocket != FREERTOS_INVALID_SOCKET ) && ( xUDPServerSocket != NULL ) );
- xEchoServerAddress.sin_port = FreeRTOS_htons( ipconfigIPERF_UDP_ECHO_PORT );
- FreeRTOS_setsockopt( xUDPServerSocket, 0, FREERTOS_SO_RCVTIMEO, &xNoTimeOut, sizeof( xNoTimeOut ) );
- xBindResult = FreeRTOS_bind( xUDPServerSocket, &xEchoServerAddress, sizeof xEchoServerAddress );
- FreeRTOS_printf( ( "vIPerfTask: created UDP server socket %p bind port %u: %ld\n",
- xUDPServerSocket, ipconfigIPERF_UDP_ECHO_PORT, xBindResult ) );
- xBindResult = xBindResult;
- #if( ipconfigUSE_CALLBACKS == 0 )
- {
- FreeRTOS_FD_SET( xUDPServerSocket, xSocketSet, eSELECT_READ );
- }
- #else
- {
- F_TCP_UDP_Handler_t xHandler;
- memset( &xHandler, '\0', sizeof ( xHandler ) );
- xHandler.pOnUdpReceive = xOnUdpReceive;
- FreeRTOS_setsockopt( xUDPServerSocket, 0, FREERTOS_SO_UDP_RECV_HANDLER, ( void * ) &xHandler, sizeof( xHandler ) );
- }
- #endif /* ipconfigUSE_CALLBACKS */
- return xUDPServerSocket;
- }
- #endif /* ipconfigIPERF_HAS_UDP */
- void vIPerfTask( void *pvParameter )
- {
- #if( ipconfigIPERF_HAS_TCP != 0 )
- Socket_t xTCPServerSocket;
- #endif /* ipconfigIPERF_HAS_TCP */
- #if( ipconfigIPERF_HAS_UDP != 0 )
- Socket_t xUDPServerSocket;
- #endif /* ipconfigIPERF_HAS_UDP */
- ( void ) pvParameter;
- xSocketSet = FreeRTOS_CreateSocketSet( );
- vListInitialise( &xTCPClientList );
- #if( ipconfigIPERF_HAS_TCP != 0 )
- {
- xTCPServerSocket = xCreateTCPServerSocket();
- }
- #endif /* ipconfigIPERF_HAS_TCP */
- #if( ipconfigIPERF_HAS_UDP != 0 )
- {
- xUDPServerSocket = xCreateUDPServerSocket();
- (void)xUDPServerSocket;
- }
- #endif /* ipconfigIPERF_HAS_UDP */
- FreeRTOS_printf( ( "Use for example:\n" ) );
- FreeRTOS_printf( ( "iperf3 -c %lxip --port %u --bytes 100M [ -R ]\n",
- FreeRTOS_htonl( FreeRTOS_GetIPAddress() ), ipconfigIPERF_UDP_ECHO_PORT ) );
- #define HUNDREDTH_MB ( ( 1024 * 1024 ) / 100 )
- for( ;; )
- {
- BaseType_t xResult;
- const TickType_t xBlockingTime = pdMS_TO_TICKS( ipconfigIPERF_LOOP_BLOCKING_TIME_MS );
- /* Wait at most 5 seconds. */
- xResult = FreeRTOS_select( xSocketSet, xBlockingTime );
- #if( ipconfigIPERF_HAS_TCP != 0 )
- if( xResult != 0 )
- {
- const MiniListItem_t* pxEnd;
- const ListItem_t *pxIterator;
- pxEnd = ( const MiniListItem_t* ) listGET_END_MARKER( &xTCPClientList );
- vIPerfServerWork( xTCPServerSocket );
- /* Check all TCP clients: */
- for( pxIterator = ( const ListItem_t * ) listGET_NEXT( pxEnd );
- pxIterator != ( const ListItem_t * ) pxEnd;
- )
- {
- TcpClient_t *pxClient;
- pxClient = ( TcpClient_t * ) listGET_LIST_ITEM_OWNER( pxIterator );
- /* Let the iterator point to the next element before the current element
- removes itself from the list. */
- pxIterator = ( const ListItem_t * ) listGET_NEXT( pxIterator );
- vIPerfTCPWork( pxClient );
- }
- }
- #endif /* ipconfigIPERF_HAS_TCP */
- #if( ipconfigIPERF_HAS_UDP != 0 )
- #if( ipconfigUSE_CALLBACKS == 0 )
- if( xResult != 0 )
- {
- vIPerfUDPWork( xUDPServerSocket );
- }
- else
- #endif /* ipconfigUSE_CALLBACKS */
- {
- if( ulUDPRecvCountSeen != ulUDPRecvCount )
- {
- /* The amount is still changing, do not show it yet. */
- ulUDPRecvCountSeen = ulUDPRecvCount;
- }
- else if( ulUDPRecvCountShown != ulUDPRecvCount )
- {
- uint32_t ulNewBytes = ulUDPRecvCount - ulUDPRecvCountShown;
- uint32_t ulMB = (ulNewBytes + HUNDREDTH_MB/2) / HUNDREDTH_MB;
- FreeRTOS_printf( ( "UDP received %lu + %lu (%lu.%02lu MB) = %lu\n",
- ulUDPRecvCountShown,
- ulNewBytes,
- ulMB / 100,
- ulMB % 100,
- ulUDPRecvCount ) );
- ulUDPRecvCountShown = ulUDPRecvCount;
- ulMB = ulMB;
- }
- }
- #endif /* ipconfigIPERF_HAS_UDP */
- }
- }
- //?¡è¡§|¡§¡ã?¨¢¡§a?¡ìWiFi??¡ì?|¨¬2a¡§o?
- #define IPERF_BUFSZ (4 * 1024)
- typedef unsigned int u32_t;
- static TaskHandle_t iperf_task_handle = NULL;
- static int flag_start_iperf = 0;
- static char gaddr[4] = {0};
- static int gport = 0;
- static u32_t sys_now(void)
- {
- return xTaskGetTickCount() * portTICK_PERIOD_MS;
- }
- static void iperf_client(const char * ipaddr, int port)
- {
- Socket_t sock;
- int i;
- //struct sockaddr_in client_addr;
- struct freertos_sockaddr client_addr;
- uint8_t* send_buf;
- u32_t tick1, tick2;
- uint64_t sentlen;
- (void)ipaddr;
- (void)port;
-
- send_buf = (uint8_t *) pvPortMalloc(IPERF_BUFSZ);
- if (!send_buf)
- return ;
- for(i = 0; i < IPERF_BUFSZ; i ++)
- send_buf[i] = i & 0xff;
- while(flag_start_iperf) {
- sock = FreeRTOS_socket( FREERTOS_AF_INET, FREERTOS_SOCK_STREAM, FREERTOS_IPPROTO_TCP );
- if (sock == FREERTOS_INVALID_SOCKET) {
- printf("Socket error\r\n");
- vTaskDelay(pdMS_TO_TICKS(100));
- continue;
- }
- client_addr.sin_port = FreeRTOS_htons( gport );
- client_addr.sin_addr = FreeRTOS_inet_addr_quick( gaddr[0],
- gaddr[1],
- gaddr[2],
- gaddr[3] );
- //memset(&(client_addr.sin_zero), 0, sizeof(client_addr.sin_zero));
-
- if (FreeRTOS_connect(sock, &client_addr, sizeof( struct freertos_sockaddr )) != 0) {
- printf("Connect failed!\r\n");
- FreeRTOS_closesocket(sock);
- vTaskDelay(10);
- continue;
- }
- printf("Connect to iperf server successful!\r\n");
- tick1 = sys_now();
- while (flag_start_iperf) {
- tick2 = sys_now();
- if(tick2 - tick1 >= configTICK_RATE_HZ * 5) {
- float f;
- f = (float)(sentlen * configTICK_RATE_HZ/125/(tick2 - tick1));
- f /= 1000.0f;
- printf("\r\nsend speed = %.4f Mbps!\r\n", f);
- tick1 = tick2;
- sentlen = 0;
- }
- if(FreeRTOS_send(sock, send_buf, IPERF_BUFSZ, 0) < 0) {
- printf("FreeRTOS_send failed\r\n");
- break;
- } else {
- sentlen += IPERF_BUFSZ;
- }
- }
- FreeRTOS_closesocket(sock);
- }
- if (send_buf) {
- vPortFree(send_buf);
- }
- }
- static void iperf_task_proc(void* arg)
- {
- iperf_client(NULL, 0);
- vTaskDelete(NULL);
- }
- void start_iperf_client(const char* ip, int port)
- {
- if (flag_start_iperf) {
- printf("iperf client has been started");
- return;
- }
- if (iperf_task_handle == NULL) {
- sscanf(ip, "%d.%d.%d.%d", (int*)&gaddr[0], (int*)&gaddr[1], (int*)&gaddr[2], (int*)&gaddr[3]);
- gport = port;
- flag_start_iperf = 1;
- xTaskCreate(iperf_task_proc, "iperf task task", 512, NULL, configMAX_PRIORITIES / 3, &iperf_task_handle);
- }
- }
|