+++ /dev/null
-/** @file\r
- Data source for network testing.\r
-\r
- Copyright (c) 2011-2012, Intel Corporation. All rights reserved.\r
- SPDX-License-Identifier: BSD-2-Clause-Patent\r
-\r
-**/\r
-\r
-#include <errno.h>\r
-#include <Uefi.h>\r
-\r
-#include <Library/BaseMemoryLib.h>\r
-#include <Library/DebugLib.h>\r
-#include <Library/PcdLib.h>\r
-#include <Library/UefiBootServicesTableLib.h>\r
-#include <Library/UefiLib.h>\r
-\r
-#include <netinet/in.h>\r
-\r
-#include <Protocol/ServiceBinding.h>\r
-#include <Protocol/Tcp4.h>\r
-\r
-#include <sys/EfiSysCall.h>\r
-#include <sys/poll.h>\r
-#include <sys/socket.h>\r
-\r
-#include <stdio.h>\r
-#include <string.h>\r
-\r
-\r
-#define DATA_SAMPLE_SHIFT 5 ///< Shift for number of samples\r
-#define RANGE_SWITCH ( 1024 * 1024 ) ///< Switch display ranges\r
-#define DATA_RATE_UPDATE_SHIFT 2 ///< 2n seconds between updates\r
-#define AVERAGE_SHIFT_COUNT ( 6 - DATA_RATE_UPDATE_SHIFT ) ///< 2n samples in average\r
-#define DATA_SAMPLES ( 1 << DATA_SAMPLE_SHIFT ) ///< Number of samples\r
-\r
-#define TPL_DATASOURCE TPL_CALLBACK ///< Synchronization TPL\r
-\r
-#define PACKET_SIZE 1448 ///< Size of data packets\r
-#define DATA_BUFFER_SIZE (( 65536 / PACKET_SIZE ) * PACKET_SIZE ) ///< Buffer size in bytes\r
-\r
-\r
-//\r
-// Socket Data\r
-//\r
-int Socket = -1;\r
-\r
-//\r
-// TCP V4 Data\r
-//\r
-BOOLEAN bTcp4; ///< TRUE if TCP4 is being used\r
-BOOLEAN bTcp4Connected; ///< TRUE if connected to remote system\r
-BOOLEAN bTcp4Connecting; ///< TRUE while connection in progress\r
-UINTN Tcp4Index; ///< Index into handle array\r
-EFI_HANDLE Tcp4Controller; ///< Network controller handle\r
-EFI_HANDLE Tcp4Handle; ///< TCP4 port handle\r
-EFI_TCP4_PROTOCOL * pTcp4Protocol; ///< TCP4 protocol pointer\r
-EFI_SERVICE_BINDING_PROTOCOL * pTcp4Service; ///< TCP4 Service binding\r
-EFI_TCP4_CONFIG_DATA Tcp4ConfigData;///< TCP4 configuration data\r
-EFI_TCP4_OPTION Tcp4Option; ///< TCP4 port options\r
-EFI_TCP4_CLOSE_TOKEN Tcp4CloseToken;///< Close control\r
-EFI_TCP4_CONNECTION_TOKEN Tcp4ConnectToken; ///< Connection control\r
-EFI_TCP4_LISTEN_TOKEN Tcp4ListenToken; ///< Listen control\r
-EFI_TCP4_IO_TOKEN Tcp4TxToken; ///< Normal data token\r
-\r
-//\r
-// Timer Data\r
-//\r
-volatile BOOLEAN bTick;\r
-BOOLEAN bTimerRunning;\r
-EFI_EVENT pTimer;\r
-\r
-//\r
-// Remote IP Address Data\r
-//\r
-struct sockaddr_in6 RemoteHostAddress;\r
-CHAR8 * pRemoteHost;\r
-\r
-//\r
-// Traffic Data\r
-//\r
-UINT64 TotalBytesSent;\r
-UINT32 In;\r
-UINT32 Samples;\r
-UINT64 BytesSent[ DATA_SAMPLES ];\r
-UINT8 Buffer[ DATA_BUFFER_SIZE ];\r
-\r
-\r
-//\r
-// Forward routine declarations\r
-//\r
-EFI_STATUS TimerStart ( UINTN Milliseconds );\r
-\r
-\r
-/**\r
- Check for control C entered at console\r
-\r
- @retval EFI_SUCCESS Control C not entered\r
- @retval EFI_ABORTED Control C entered\r
-**/\r
-EFI_STATUS\r
-ControlCCheck (\r
- )\r
-{\r
- EFI_STATUS Status;\r
-\r
- //\r
- // Assume no user intervention\r
- //\r
- Status = EFI_SUCCESS;\r
-\r
- //\r
- // Display user stop request\r
- //\r
- if ( EFI_ERROR ( Status )) {\r
- DEBUG (( DEBUG_INFO,\r
- "User stop request!\r\n" ));\r
- }\r
-\r
- //\r
- // Return the check status\r
- //\r
- return Status;\r
-}\r
-\r
-\r
-/**\r
- Get a digit\r
-\r
- @param [in] pDigit The address of the next digit\r
- @param [out] pValue The address to receive the value\r
-\r
- @return Returns the address of the separator\r
-\r
-**/\r
-CHAR8 *\r
-GetDigit (\r
- CHAR8 * pDigit,\r
- UINT32 * pValue\r
- )\r
-{\r
- UINT32 Value;\r
-\r
- //\r
- // Walk the digits\r
- //\r
- Value = 0;\r
- while (( '0' <= *pDigit ) && ( '9' >= *pDigit )) {\r
- //\r
- // Make room for the new least significant digit\r
- //\r
- Value *= 10;\r
-\r
- //\r
- // Convert the digit from ASCII to binary\r
- //\r
- Value += *pDigit - '0';\r
-\r
- //\r
- // Set the next digit\r
- //\r
- pDigit += 1;\r
- }\r
-\r
- //\r
- // Return the value\r
- //\r
- *pValue = Value;\r
-\r
- //\r
- // Return the next separator\r
- //\r
- return pDigit;\r
-}\r
-\r
-\r
-/**\r
- Get the IP address\r
-\r
- @retval EFI_SUCCESS The IP address is valid\r
- @retval Other Failure to convert the IP address\r
-**/\r
-EFI_STATUS\r
-IpAddress (\r
- )\r
-{\r
- struct sockaddr_in * pRemoteAddress4;\r
- struct sockaddr_in6 * pRemoteAddress6;\r
- UINT32 RemoteAddress;\r
- EFI_STATUS Status;\r
- UINT32 Value1;\r
- UINT32 Value2;\r
- UINT32 Value3;\r
- UINT32 Value4;\r
- UINT32 Value5;\r
- UINT32 Value6;\r
- UINT32 Value7;\r
- UINT32 Value8;\r
-\r
- //\r
- // Assume failure\r
- //\r
- Status = EFI_INVALID_PARAMETER;\r
-\r
- //\r
- // Get the port number\r
- //\r
- ZeroMem ( &RemoteHostAddress, sizeof ( RemoteHostAddress ));\r
- RemoteHostAddress.sin6_port = htons ( PcdGet16 ( DataSource_Port ));\r
- pRemoteAddress4 = (struct sockaddr_in *)&RemoteHostAddress;\r
- pRemoteAddress6 = &RemoteHostAddress;\r
- \r
- //\r
- // Convert the IP address from a string to a numeric value\r
- //\r
- if (( 4 == sscanf ( pRemoteHost,\r
- "%d.%d.%d.%d",\r
- &Value1,\r
- &Value2,\r
- &Value3,\r
- &Value4 ))\r
- && ( 255 >= Value1 )\r
- && ( 255 >= Value2 )\r
- && ( 255 >= Value3 )\r
- && ( 255 >= Value4 )) {\r
- //\r
- // Build the IPv4 address\r
- //\r
- pRemoteAddress4->sin_len = sizeof ( *pRemoteAddress4 );\r
- pRemoteAddress4->sin_family = AF_INET;\r
- RemoteAddress = Value1\r
- | ( Value2 << 8 )\r
- | ( Value3 << 16 )\r
- | ( Value4 << 24 );\r
- pRemoteAddress4->sin_addr.s_addr = RemoteAddress;\r
- Status = EFI_SUCCESS;\r
-\r
- //\r
- // Display the IP address\r
- //\r
- DEBUG (( DEBUG_INFO,\r
- "%d.%d.%d.%d: Remote host IP address\r\n",\r
- Value1,\r
- Value2,\r
- Value3,\r
- Value4 ));\r
- }\r
- else if (( 8 == sscanf ( pRemoteHost,\r
- "%x:%x:%x:%x:%x:%x:%x:%x",\r
- &Value1,\r
- &Value2,\r
- &Value3,\r
- &Value4,\r
- &Value5,\r
- &Value6,\r
- &Value7,\r
- &Value8 ))\r
- && ( 0xffff >= Value1 )\r
- && ( 0xffff >= Value2 )\r
- && ( 0xffff >= Value3 )\r
- && ( 0xffff >= Value4 )\r
- && ( 0xffff >= Value5 )\r
- && ( 0xffff >= Value6 )\r
- && ( 0xffff >= Value7 )\r
- && ( 0xffff >= Value8 )) {\r
- //\r
- // Build the IPv6 address\r
- //\r
- pRemoteAddress6->sin6_len = sizeof ( *pRemoteAddress6 );\r
- pRemoteAddress6->sin6_family = AF_INET6;\r
- pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 0 ] = (UINT8)( Value1 >> 8 );\r
- pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 1 ] = (UINT8)Value1;\r
- pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 2 ] = (UINT8)( Value2 >> 8 );\r
- pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 3 ] = (UINT8)Value2;\r
- pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 4 ] = (UINT8)( Value3 >> 8 );\r
- pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 5 ] = (UINT8)Value3;\r
- pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 6 ] = (UINT8)( Value4 >> 8 );\r
- pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 7 ] = (UINT8)Value4;\r
- pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 8 ] = (UINT8)( Value5 >> 8 );\r
- pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 9 ] = (UINT8)Value5;\r
- pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 10 ] = (UINT8)( Value6 >> 8 );\r
- pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 11 ] = (UINT8)Value6;\r
- pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 12 ] = (UINT8)( Value7 >> 8 );\r
- pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 13 ] = (UINT8)Value7;\r
- pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 14 ] = (UINT8)( Value8 >> 8 );\r
- pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 15 ] = (UINT8)Value8;\r
- Status = EFI_SUCCESS;\r
-\r
- //\r
- // Display the IP address\r
- //\r
- DEBUG (( DEBUG_INFO,\r
- "[%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x]: Remote host IP address\r\n",\r
- Value1,\r
- Value2,\r
- Value3,\r
- Value4,\r
- Value5,\r
- Value6,\r
- Value7,\r
- Value8 ));\r
- }\r
- else {\r
- Print ( L"ERROR - Invalid IP address!\r\n" );\r
- }\r
-\r
- //\r
- // Return the operation status\r
- //\r
- return Status;\r
-}\r
-\r
-\r
-/**\r
- Close the socket\r
-\r
- @retval EFI_SUCCESS The application is running normally\r
- @retval Other The user stopped the application\r
-**/\r
-EFI_STATUS\r
-SocketClose (\r
- )\r
-{\r
- int CloseStatus;\r
- EFI_STATUS Status;\r
-\r
- //\r
- // Determine if the socket is open\r
- //\r
- Status = EFI_DEVICE_ERROR;\r
- if ( -1 != Socket ) {\r
- //\r
- // Attempt to close the socket\r
- //\r
- CloseStatus = close ( Socket );\r
- if ( 0 == CloseStatus ) {\r
- DEBUG (( DEBUG_INFO,\r
- "0x%08x: Socket closed\r\n",\r
- Socket ));\r
- Socket = -1;\r
- Status = EFI_SUCCESS;\r
- }\r
- else {\r
- DEBUG (( DEBUG_ERROR,\r
- "ERROR: Failed to close socket, errno: %d\r\n",\r
- errno ));\r
- }\r
- }\r
-\r
- //\r
- // Return the operation status\r
- //\r
- return Status;\r
-}\r
-\r
-\r
-/**\r
- Connect the socket\r
-\r
- @retval EFI_SUCCESS The application is running normally\r
- @retval Other The user stopped the application\r
-**/\r
-EFI_STATUS\r
-SocketConnect (\r
- )\r
-{\r
- int ConnectStatus;\r
- struct sockaddr_in * pRemoteAddress4;\r
- struct sockaddr_in6 * pRemoteAddress6;\r
- EFI_STATUS Status;\r
-\r
- //\r
- // Display the connecting message\r
- //\r
- pRemoteAddress4 = (struct sockaddr_in *)&RemoteHostAddress;\r
- pRemoteAddress6 = &RemoteHostAddress;\r
- if ( AF_INET == pRemoteAddress6->sin6_family ) {\r
- Print ( L"Connecting to remote system %d.%d.%d.%d:%d\r\n",\r
- pRemoteAddress4->sin_addr.s_addr & 0xff,\r
- ( pRemoteAddress4->sin_addr.s_addr >> 8 ) & 0xff,\r
- ( pRemoteAddress4->sin_addr.s_addr >> 16 ) & 0xff,\r
- ( pRemoteAddress4->sin_addr.s_addr >> 24 ) & 0xff,\r
- ntohs ( pRemoteAddress4->sin_port ));\r
- }\r
- else {\r
- Print ( L"Connecting to remote system [%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]:%d\r\n",\r
- pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 0 ],\r
- pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 1 ],\r
- pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 2 ],\r
- pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 3 ],\r
- pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 4 ],\r
- pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 5 ],\r
- pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 6 ],\r
- pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 7 ],\r
- pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 8 ],\r
- pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 9 ],\r
- pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 10 ],\r
- pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 11 ],\r
- pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 12 ],\r
- pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 13 ],\r
- pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 14 ],\r
- pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 15 ],\r
- ntohs ( pRemoteAddress6->sin6_port ));\r
- }\r
-\r
- //\r
- // Connect to the remote system\r
- //\r
- Status = EFI_SUCCESS;\r
- do {\r
- //\r
- // Check for user stop request\r
- //\r
- while ( !bTick ) {\r
- Status = ControlCCheck ( );\r
- if ( EFI_ERROR ( Status )) {\r
- break;\r
- }\r
- }\r
- bTick = FALSE;\r
- if ( EFI_ERROR ( Status )) {\r
- break;\r
- }\r
-\r
- //\r
- // Connect to the remote system\r
- //\r
- ConnectStatus = connect ( Socket,\r
- (struct sockaddr *)pRemoteAddress6,\r
- pRemoteAddress6->sin6_len );\r
- if ( -1 != ConnectStatus ) {\r
- if ( AF_INET == pRemoteAddress6->sin6_family ) {\r
- Print ( L"Connected to remote system %d.%d.%d.%d:%d\r\n",\r
- pRemoteAddress4->sin_addr.s_addr & 0xff,\r
- ( pRemoteAddress4->sin_addr.s_addr >> 8 ) & 0xff,\r
- ( pRemoteAddress4->sin_addr.s_addr >> 16 ) & 0xff,\r
- ( pRemoteAddress4->sin_addr.s_addr >> 24 ) & 0xff,\r
- ntohs ( pRemoteAddress4->sin_port ));\r
- }\r
- else {\r
- Print ( L"Connected to remote system [%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]:%d\r\n",\r
- pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 0 ],\r
- pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 1 ],\r
- pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 2 ],\r
- pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 3 ],\r
- pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 4 ],\r
- pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 5 ],\r
- pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 6 ],\r
- pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 7 ],\r
- pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 8 ],\r
- pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 9 ],\r
- pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 10 ],\r
- pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 11 ],\r
- pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 12 ],\r
- pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 13 ],\r
- pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 14 ],\r
- pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 15 ],\r
- ntohs ( pRemoteAddress6->sin6_port ));\r
- }\r
-Print ( L"ConnectStatus: %d, Status: %r\r\n", ConnectStatus, Status );\r
- }\r
- else {\r
- //\r
- // Close the socket and try again\r
- //\r
- if ( EAGAIN != errno ) {\r
- Status = EFI_NOT_STARTED;\r
- break;\r
- }\r
- }\r
- } while ( -1 == ConnectStatus );\r
-\r
- //\r
- // Return the operation status\r
- //\r
-Print ( L"SocketConnect returning Status: %r\r\n", Status );\r
- return Status;\r
-}\r
-\r
-\r
-/**\r
- Create the socket\r
-\r
- @param [in] Family Network family, AF_INET or AF_INET6\r
-\r
- @retval EFI_SUCCESS The application is running normally\r
- @retval Other The user stopped the application\r
-**/\r
-EFI_STATUS\r
-SocketNew (\r
- sa_family_t Family\r
- )\r
-{\r
- EFI_STATUS Status;\r
-\r
- //\r
- // Loop creating the socket\r
- //\r
- DEBUG (( DEBUG_INFO,\r
- "Creating the socket\r\n" ));\r
- do {\r
- //\r
- // Check for user stop request\r
- //\r
- Status = ControlCCheck ( );\r
- if ( EFI_ERROR ( Status )) {\r
- break;\r
- }\r
-\r
- //\r
- // Attempt to create the socket\r
- //\r
- Socket = socket ( Family,\r
- SOCK_STREAM,\r
- IPPROTO_TCP );\r
- if ( -1 != Socket ) {\r
- DEBUG (( DEBUG_INFO,\r
- "0x%08x: Socket created\r\n",\r
- Socket ));\r
- break;\r
- }\r
- } while ( -1 == Socket );\r
-\r
- //\r
- // Return the operation status\r
- //\r
- return Status;\r
-}\r
-\r
-\r
-/**\r
- Send data over the socket\r
-\r
- @retval EFI_SUCCESS The application is running normally\r
- @retval Other The user stopped the application\r
-**/\r
-EFI_STATUS\r
-SocketSend (\r
- )\r
-{\r
- size_t BytesSent;\r
- EFI_STATUS Status;\r
- EFI_TPL TplPrevious;\r
-\r
- //\r
- // Restart the timer\r
- //\r
- TimerStart ( 1 * 1000 );\r
-\r
- //\r
- // Loop until the connection breaks or the user stops\r
- //\r
- do {\r
- //\r
- // Check for user stop request\r
- //\r
- Status = ControlCCheck ( );\r
- if ( EFI_ERROR ( Status )) {\r
- break;\r
- }\r
-\r
- //\r
- // Send some bytes\r
- //\r
- BytesSent = write ( Socket, &Buffer[0], sizeof ( Buffer ));\r
- if ( -1 == BytesSent ) {\r
- DEBUG (( DEBUG_INFO,\r
- "ERROR: send failed, errno: %d\r\n",\r
- errno ));\r
-Print ( L"ERROR: send failed, errno: %d\r\n", errno );\r
-\r
- //\r
- // Try again\r
- //\r
- Status = EFI_SUCCESS;\r
-\r
-//\r
-// Exit now\r
-//\r
-Status = EFI_NOT_STARTED;\r
- break;\r
- }\r
-\r
- //\r
- // Synchronize with the TimerCallback routine\r
- //\r
- TplPrevious = gBS->RaiseTPL ( TPL_DATASOURCE );\r
-\r
- //\r
- // Account for the data sent\r
- //\r
- TotalBytesSent += BytesSent;\r
-\r
- //\r
- // Release the TimerCallback routine synchronization\r
- //\r
- gBS->RestoreTPL ( TplPrevious );\r
- } while ( !EFI_ERROR ( Status ));\r
-\r
- //\r
- // Return the operation status\r
- //\r
- return Status;\r
-}\r
-\r
-\r
-/**\r
- Open the network connection and send the data.\r
-\r
- @retval EFI_SUCCESS Continue looping\r
- @retval other Stopped by user's Control-C input\r
-\r
-**/\r
-EFI_STATUS\r
-SocketOpen (\r
- )\r
-{\r
- EFI_STATUS Status;\r
-\r
- //\r
- // Use do/while and break instead of goto\r
- //\r
- do {\r
- //\r
- // Wait for the network layer to initialize\r
- //\r
- Status = SocketNew ( RemoteHostAddress.sin6_family );\r
- if ( EFI_ERROR ( Status )) {\r
- break;\r
- }\r
-\r
- //\r
- // Wait for the remote network application to start\r
- //\r
- Status = SocketConnect ( );\r
-Print ( L"Status: %r\r\n", Status );\r
- if ( EFI_NOT_STARTED == Status ) {\r
- Status = SocketClose ( );\r
- continue;\r
- }\r
- else if ( EFI_SUCCESS != Status ) {\r
- //\r
- // Control-C\r
- //\r
- break;\r
- }\r
-\r
- //\r
- // Send data until the connection breaks\r
- //\r
- Status = SocketSend ( );\r
- if ( EFI_ERROR ( Status )) {\r
- break;\r
- }\r
- } while ( FALSE );\r
-\r
- //\r
- // Return the operation status\r
- //\r
-Print ( L"Returning Status: %r\r\n", Status );\r
- return Status;\r
-}\r
-\r
-\r
-/**\r
- Close the TCP connection\r
-\r
- @retval EFI_SUCCESS The application is running normally\r
- @retval Other The user stopped the application\r
-**/\r
-EFI_STATUS\r
-Tcp4Close (\r
- )\r
-{\r
- UINTN Index;\r
- UINT8 * pIpAddress;\r
- EFI_STATUS Status;\r
-\r
- //\r
- // Close the port\r
- //\r
- if ( bTcp4Connected ) {\r
- Tcp4CloseToken.AbortOnClose = TRUE;\r
- Status = pTcp4Protocol->Close ( pTcp4Protocol,\r
- &Tcp4CloseToken );\r
- if ( EFI_ERROR ( Status )) {\r
- DEBUG (( DEBUG_ERROR,\r
- "ERROR - Failed to start the TCP port close, Status: %r\r\n",\r
- Status ));\r
- }\r
- else {\r
- Status = gBS->WaitForEvent ( 1,\r
- &Tcp4CloseToken.CompletionToken.Event,\r
- &Index );\r
- if ( EFI_ERROR ( Status )) {\r
- DEBUG (( DEBUG_ERROR,\r
- "ERROR - Failed to wait for close event, Status: %r\r\n",\r
- Status ));\r
- }\r
- else {\r
- Status = Tcp4CloseToken.CompletionToken.Status;\r
- if ( EFI_ERROR ( Status )) {\r
- DEBUG (( DEBUG_ERROR,\r
- "ERROR - Failed to close the TCP port, Status: %r\r\n",\r
- Status ));\r
- }\r
- else {\r
- DEBUG (( DEBUG_INFO,\r
- "0x%08x: TCP port closed\r\n",\r
- pTcp4Protocol ));\r
- bTcp4Connected = FALSE;\r
-\r
- //\r
- // Display the port closed message\r
- //\r
- pIpAddress = (UINT8 *)&((struct sockaddr_in *)&RemoteHostAddress)->sin_addr.s_addr;\r
- Print ( L"Closed connection to %d.%d.%d.%d:%d\r\n",\r
- pIpAddress[0],\r
- pIpAddress[1],\r
- pIpAddress[2],\r
- pIpAddress[3],\r
- ntohs ( ((struct sockaddr_in *)&RemoteHostAddress)->sin_port ));\r
- }\r
- }\r
- }\r
- }\r
-\r
- //\r
- // Release the events\r
- //\r
- if ( NULL != Tcp4TxToken.CompletionToken.Event ) {\r
- Status = gBS->CloseEvent ( Tcp4TxToken.CompletionToken.Event );\r
- if ( !EFI_ERROR ( Status )) {\r
- DEBUG (( DEBUG_INFO,\r
- "0x%08x: TX event closed\r\n",\r
- Tcp4TxToken.CompletionToken.Event ));\r
- Tcp4TxToken.CompletionToken.Event = NULL;\r
- }\r
- else {\r
- DEBUG (( DEBUG_ERROR,\r
- "ERROR - Failed to close the Tcp4TxToken event, Status: %r\r\n",\r
- Status ));\r
- }\r
- }\r
-\r
- if ( NULL != Tcp4ListenToken.CompletionToken.Event ) {\r
- Status = gBS->CloseEvent ( Tcp4ListenToken.CompletionToken.Event );\r
- if ( !EFI_ERROR ( Status )) {\r
- DEBUG (( DEBUG_INFO,\r
- "0x%08x: Listen event closed\r\n",\r
- Tcp4ListenToken.CompletionToken.Event ));\r
- Tcp4ListenToken.CompletionToken.Event = NULL;\r
- }\r
- else {\r
- DEBUG (( DEBUG_ERROR,\r
- "ERROR - Failed to close the Tcp4ListenToken event, Status: %r\r\n",\r
- Status ));\r
- }\r
- }\r
-\r
- if ( NULL != Tcp4ConnectToken.CompletionToken.Event ) {\r
- Status = gBS->CloseEvent ( Tcp4ConnectToken.CompletionToken.Event );\r
- if ( !EFI_ERROR ( Status )) {\r
- DEBUG (( DEBUG_INFO,\r
- "0x%08x: Connect event closed\r\n",\r
- Tcp4ConnectToken.CompletionToken.Event ));\r
- Tcp4ConnectToken.CompletionToken.Event = NULL;\r
- }\r
- else {\r
- DEBUG (( DEBUG_ERROR,\r
- "ERROR - Failed to close the Tcp4ConnectToken event, Status: %r\r\n",\r
- Status ));\r
- }\r
- }\r
-\r
- if ( NULL != Tcp4CloseToken.CompletionToken.Event ) {\r
- Status = gBS->CloseEvent ( Tcp4CloseToken.CompletionToken.Event );\r
- if ( !EFI_ERROR ( Status )) {\r
- DEBUG (( DEBUG_INFO,\r
- "0x%08x: Close event closed\r\n",\r
- Tcp4CloseToken.CompletionToken.Event ));\r
- Tcp4CloseToken.CompletionToken.Event = NULL;\r
- }\r
- else {\r
- DEBUG (( DEBUG_ERROR,\r
- "ERROR - Failed to close the Tcp4CloseToken event, Status: %r\r\n",\r
- Status ));\r
- }\r
- }\r
-\r
- //\r
- // Close the TCP protocol\r
- //\r
- if ( NULL != pTcp4Protocol ) {\r
- Status = gBS->CloseProtocol ( Tcp4Handle,\r
- &gEfiTcp4ProtocolGuid,\r
- gImageHandle,\r
- NULL );\r
- if ( EFI_ERROR ( Status )) {\r
- DEBUG (( DEBUG_ERROR,\r
- "ERROR - Failed to close the TCP protocol, Status: %r\r\n",\r
- Status ));\r
- }\r
- else {\r
- DEBUG (( DEBUG_INFO,\r
- "0x%08x: TCP4 protocol closed\r\n",\r
- pTcp4Protocol ));\r
- pTcp4Protocol = NULL;\r
- }\r
- }\r
-\r
- //\r
- // Done with the TCP service\r
- //\r
- if ( NULL != Tcp4Handle ) {\r
- Status = pTcp4Service->DestroyChild ( pTcp4Service,\r
- Tcp4Handle );\r
- if ( EFI_ERROR ( Status )) {\r
- DEBUG (( DEBUG_ERROR,\r
- "ERROR - Failed to release TCP service handle, Status: %r\r\n",\r
- Status ));\r
- }\r
- else {\r
- DEBUG (( DEBUG_INFO,\r
- "Ox%08x: TCP service closed\r\n",\r
- Tcp4Handle ));\r
- Tcp4Handle = NULL;\r
- }\r
- }\r
-\r
- //\r
- // Close the service protocol\r
- //\r
- if ( NULL != pTcp4Service ) {\r
- Status = gBS->CloseProtocol ( Tcp4Controller,\r
- &gEfiTcp4ServiceBindingProtocolGuid,\r
- gImageHandle,\r
- NULL );\r
- if ( !EFI_ERROR ( Status )) {\r
- DEBUG (( DEBUG_INFO,\r
- "0x%08x: Controller closed gEfiTcp4ServiceBindingProtocolGuid protocol\r\n",\r
- Tcp4Controller ));\r
- pTcp4Service = NULL;\r
- }\r
- else {\r
- DEBUG (( DEBUG_ERROR,\r
- "ERROR - Failed to close the gEfiTcp4ServiceBindingProtocolGuid protocol, Status: %r\r\n",\r
- Status ));\r
- }\r
- }\r
- Tcp4Controller = NULL;\r
- bTcp4Connecting = TRUE;\r
-\r
- //\r
- // Mark the connection as closed\r
- //\r
- Status = EFI_SUCCESS;\r
-\r
- //\r
- // Return the operation status\r
- //\r
- return Status;\r
-}\r
-\r
-\r
-/**\r
- Locate TCP protocol\r
-\r
- @retval EFI_SUCCESS Protocol found\r
- @retval other Protocl not found\r
-**/\r
-EFI_STATUS\r
-Tcp4Locate (\r
- )\r
-{\r
- UINTN HandleCount;\r
- EFI_HANDLE * pHandles;\r
- UINT8 * pIpAddress;\r
- EFI_STATUS Status;\r
-\r
- //\r
- // Use do/while and break instead of goto\r
- //\r
- do {\r
- //\r
- // Attempt to locate the next TCP adapter in the system\r
- //\r
- Status = gBS->LocateHandleBuffer ( ByProtocol,\r
- &gEfiTcp4ServiceBindingProtocolGuid,\r
- NULL,\r
- &HandleCount,\r
- &pHandles );\r
- if ( EFI_ERROR ( Status )) {\r
- DEBUG (( DEBUG_WARN,\r
- "WARNING - No network controllers or TCP4 available, Status: %r\r\n",\r
- Status ));\r
- break;\r
- }\r
-\r
- //\r
- // Wrap the index if necessary\r
- //\r
- if ( HandleCount <= Tcp4Index ) {\r
- Tcp4Index = 0;\r
-\r
- //\r
- // Wait for the next timer tick\r
- //\r
- do {\r
- } while ( !bTick );\r
- bTick = FALSE;\r
- }\r
-\r
- //\r
- // Display the connecting message\r
- //\r
- if ( bTcp4Connecting ) {\r
- pIpAddress = (UINT8 *)&((struct sockaddr_in *)&RemoteHostAddress)->sin_addr.s_addr;\r
- Print ( L"Connecting to %d.%d.%d.%d:%d\r\n",\r
- pIpAddress[0],\r
- pIpAddress[1],\r
- pIpAddress[2],\r
- pIpAddress[3],\r
- ntohs ( ((struct sockaddr_in *)&RemoteHostAddress)->sin_port ));\r
- bTcp4Connecting = FALSE;\r
- }\r
-\r
- //\r
- // Open the network controller's service protocol\r
- //\r
- Tcp4Controller = pHandles[ Tcp4Index++ ];\r
- Status = gBS->OpenProtocol (\r
- Tcp4Controller,\r
- &gEfiTcp4ServiceBindingProtocolGuid,\r
- (VOID **) &pTcp4Service,\r
- gImageHandle,\r
- NULL,\r
- EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL );\r
- if ( EFI_ERROR ( Status )) {\r
- DEBUG (( DEBUG_ERROR,\r
- "ERROR - Failed to open gEfiTcp4ServiceBindingProtocolGuid on controller 0x%08x\r\n",\r
- Tcp4Controller ));\r
- Tcp4Controller = NULL;\r
- break;\r
- }\r
- DEBUG (( DEBUG_INFO,\r
- "0x%08x: Controller opened gEfiTcp4ServiceBindingProtocolGuid protocol\r\n",\r
- Tcp4Controller ));\r
-\r
- //\r
- // Connect to the TCP service\r
- //\r
- Status = pTcp4Service->CreateChild ( pTcp4Service,\r
- &Tcp4Handle );\r
- if ( EFI_ERROR ( Status )) {\r
- DEBUG (( DEBUG_ERROR,\r
- "ERROR - Failed to open TCP service, Status: %r\r\n",\r
- Status ));\r
- Tcp4Handle = NULL;\r
- break;\r
- }\r
- DEBUG (( DEBUG_INFO,\r
- "Ox%08x: TCP service opened\r\n",\r
- Tcp4Handle ));\r
-\r
- //\r
- // Locate the TCP protcol\r
- //\r
- Status = gBS->OpenProtocol ( Tcp4Handle,\r
- &gEfiTcp4ProtocolGuid,\r
- (VOID **)&pTcp4Protocol,\r
- gImageHandle,\r
- NULL,\r
- EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL );\r
- if ( EFI_ERROR ( Status )) {\r
- DEBUG (( DEBUG_ERROR,\r
- "ERROR - Failed to open the TCP protocol, Status: %r\r\n",\r
- Status ));\r
- pTcp4Protocol = NULL;\r
- break;\r
- }\r
- DEBUG (( DEBUG_INFO,\r
- "0x%08x: TCP4 protocol opened\r\n",\r
- pTcp4Protocol ));\r
- }while ( FALSE );\r
-\r
- //\r
- // Release the handle buffer\r
- //\r
- gBS->FreePool ( pHandles );\r
-\r
- //\r
- // Return the operation status\r
- //\r
- return Status;\r
-}\r
-\r
-\r
-/**\r
- Send data over the TCP4 connection\r
-\r
- @retval EFI_SUCCESS The application is running normally\r
- @retval Other The user stopped the application\r
-**/\r
-EFI_STATUS\r
-Tcp4Send (\r
- )\r
-{\r
- UINTN Index;\r
- EFI_TCP4_TRANSMIT_DATA Packet;\r
- EFI_STATUS Status;\r
- EFI_TPL TplPrevious;\r
-\r
- //\r
- // Restart the timer\r
- //\r
- TimerStart ( 1 * 1000 );\r
-\r
- //\r
- // Initialize the packet\r
- //\r
- Packet.DataLength = sizeof ( Buffer );\r
- Packet.FragmentCount = 1;\r
- Packet.Push = FALSE;\r
- Packet.Urgent = FALSE;\r
- Packet.FragmentTable[0].FragmentBuffer = &Buffer[0];\r
- Packet.FragmentTable[0].FragmentLength = sizeof ( Buffer );\r
- Tcp4TxToken.Packet.TxData = &Packet;\r
-\r
- //\r
- // Loop until the connection breaks or the user stops\r
- //\r
- do {\r
- //\r
- // Check for user stop request\r
- //\r
- Status = ControlCCheck ( );\r
- if ( EFI_ERROR ( Status )) {\r
- break;\r
- }\r
-\r
- //\r
- // Send some bytes\r
- //\r
- Status = pTcp4Protocol->Transmit ( pTcp4Protocol,\r
- &Tcp4TxToken );\r
- if ( EFI_ERROR ( Status )) {\r
- DEBUG (( DEBUG_ERROR,\r
- "ERROR - Failed to start the transmit, Status: %r\r\n",\r
- Status ));\r
-\r
- //\r
- // Try again\r
- //\r
- Status = EFI_SUCCESS;\r
- break;\r
- }\r
-\r
- //\r
- // Wait for the transmit to complete\r
- //\r
- Status = gBS->WaitForEvent ( 1,\r
- &Tcp4TxToken.CompletionToken.Event,\r
- &Index );\r
- if ( EFI_ERROR ( Status )) {\r
- DEBUG (( DEBUG_ERROR,\r
- "ERROR - Failed to wait for transmit completion, Status: %r\r\n",\r
- Status ));\r
-\r
- //\r
- // Try again\r
- //\r
- Status = EFI_SUCCESS;\r
- break;\r
- }\r
-\r
- //\r
- // Get the transmit status\r
- //\r
- Status = Tcp4TxToken.CompletionToken.Status;\r
- if ( EFI_ERROR ( Status )) {\r
- DEBUG (( DEBUG_WARN,\r
- "WARNING - Failed the transmission, Status: %r\r\n",\r
- Status ));\r
-\r
- //\r
- // Try again\r
- //\r
- Status = EFI_SUCCESS;\r
-\r
-//\r
-// Exit now\r
-//\r
-Status = EFI_NOT_STARTED;\r
- break;\r
- }\r
-\r
- //\r
- // Synchronize with the TimerCallback routine\r
- //\r
- TplPrevious = gBS->RaiseTPL ( TPL_DATASOURCE );\r
-\r
- //\r
- // Account for the data sent\r
- //\r
- TotalBytesSent += Packet.DataLength;\r
-\r
- //\r
- // Release the TimerCallback routine synchronization\r
- //\r
- gBS->RestoreTPL ( TplPrevious );\r
- } while ( !EFI_ERROR ( Status ));\r
-\r
- //\r
- // Return the operation status\r
- //\r
- return Status;\r
-}\r
-\r
-\r
-/**\r
- Open the network connection and send the data.\r
-\r
- @retval EFI_SUCCESS Continue looping\r
- @retval other Stopped by user's Control-C input\r
-\r
-**/\r
-EFI_STATUS\r
-Tcp4Open (\r
- )\r
-{\r
- UINTN Index;\r
- UINT8 * pIpAddress;\r
- EFI_STATUS Status;\r
-\r
- //\r
- // Use do/while and break instead of goto\r
- //\r
- do {\r
- //\r
- // Locate the TCP protocol\r
- //\r
- Status = Tcp4Locate ( );\r
- if ( EFI_ERROR ( Status )) {\r
- break;\r
- }\r
-\r
- //\r
- // Create the necessary events\r
- //\r
- Status = gBS->CreateEvent ( 0,\r
- TPL_CALLBACK,\r
- NULL,\r
- NULL,\r
- &Tcp4CloseToken.CompletionToken.Event );\r
- if ( EFI_ERROR ( Status )) {\r
- DEBUG (( DEBUG_ERROR,\r
- "ERROR - Failed to create the close event, Status: %r\r\n",\r
- Status ));\r
- Tcp4CloseToken.CompletionToken.Event = NULL;\r
- break;\r
- }\r
- DEBUG (( DEBUG_INFO,\r
- "0x%08x: Close event open\r\n",\r
- Tcp4CloseToken.CompletionToken.Event ));\r
-\r
- Status = gBS->CreateEvent ( 0,\r
- TPL_CALLBACK,\r
- NULL,\r
- NULL,\r
- &Tcp4ConnectToken.CompletionToken.Event );\r
- if ( EFI_ERROR ( Status )) {\r
- DEBUG (( DEBUG_ERROR,\r
- "ERROR - Failed to create the connect event, Status: %r\r\n",\r
- Status ));\r
- Tcp4ConnectToken.CompletionToken.Event = NULL;\r
- break;\r
- }\r
- DEBUG (( DEBUG_INFO,\r
- "0x%08x: Connect event open\r\n",\r
- Tcp4ConnectToken.CompletionToken.Event ));\r
-\r
- Status = gBS->CreateEvent ( 0,\r
- TPL_CALLBACK,\r
- NULL,\r
- NULL,\r
- &Tcp4ListenToken.CompletionToken.Event );\r
- if ( EFI_ERROR ( Status )) {\r
- DEBUG (( DEBUG_ERROR,\r
- "ERROR - Failed to create the listen event, Status: %r\r\n",\r
- Status ));\r
- Tcp4ListenToken.CompletionToken.Event = NULL;\r
- break;\r
- }\r
- DEBUG (( DEBUG_INFO,\r
- "0x%08x: Listen event open\r\n",\r
- Tcp4ListenToken.CompletionToken.Event ));\r
-\r
- Status = gBS->CreateEvent ( 0,\r
- TPL_CALLBACK,\r
- NULL,\r
- NULL,\r
- &Tcp4TxToken.CompletionToken.Event );\r
- if ( EFI_ERROR ( Status )) {\r
- DEBUG (( DEBUG_ERROR,\r
- "ERROR - Failed to create the TX event, Status: %r\r\n",\r
- Status ));\r
- Tcp4TxToken.CompletionToken.Event = NULL;\r
- break;\r
- }\r
- DEBUG (( DEBUG_INFO,\r
- "0x%08x: TX event open\r\n",\r
- Tcp4TxToken.CompletionToken.Event ));\r
-\r
- //\r
- // Configure the local TCP port\r
- //\r
- Tcp4ConfigData.TimeToLive = 255;\r
- Tcp4ConfigData.TypeOfService = 0;\r
- Tcp4ConfigData.ControlOption = NULL;\r
- Tcp4ConfigData.AccessPoint.ActiveFlag = TRUE;\r
- Tcp4ConfigData.AccessPoint.StationAddress.Addr[0] = 0;\r
- Tcp4ConfigData.AccessPoint.StationAddress.Addr[1] = 0;\r
- Tcp4ConfigData.AccessPoint.StationAddress.Addr[2] = 0;\r
- Tcp4ConfigData.AccessPoint.StationAddress.Addr[3] = 0;\r
- Tcp4ConfigData.AccessPoint.StationPort = 0;\r
- Tcp4ConfigData.AccessPoint.RemoteAddress.Addr[0] = (UINT8) ((struct sockaddr_in *)&RemoteHostAddress)->sin_addr.s_addr;\r
- Tcp4ConfigData.AccessPoint.RemoteAddress.Addr[1] = (UINT8)( ((struct sockaddr_in *)&RemoteHostAddress)->sin_addr.s_addr >> 8 );\r
- Tcp4ConfigData.AccessPoint.RemoteAddress.Addr[2] = (UINT8)( ((struct sockaddr_in *)&RemoteHostAddress)->sin_addr.s_addr >> 16 );\r
- Tcp4ConfigData.AccessPoint.RemoteAddress.Addr[3] = (UINT8)( ((struct sockaddr_in *)&RemoteHostAddress)->sin_addr.s_addr >> 24 );\r
- Tcp4ConfigData.AccessPoint.RemotePort = ntohs (((struct sockaddr_in *)&RemoteHostAddress)->sin_port);\r
- Tcp4ConfigData.AccessPoint.UseDefaultAddress = TRUE;\r
- Tcp4ConfigData.AccessPoint.SubnetMask.Addr[0] = 0;\r
- Tcp4ConfigData.AccessPoint.SubnetMask.Addr[1] = 0;\r
- Tcp4ConfigData.AccessPoint.SubnetMask.Addr[2] = 0;\r
- Tcp4ConfigData.AccessPoint.SubnetMask.Addr[3] = 0;\r
- Status = pTcp4Protocol->Configure ( pTcp4Protocol,\r
- &Tcp4ConfigData );\r
- if ( EFI_ERROR ( Status )) {\r
- DEBUG (( DEBUG_ERROR,\r
- "ERROR - Failed to configure TCP port, Status: %r\r\n",\r
- Status ));\r
- break;\r
- }\r
- DEBUG (( DEBUG_INFO,\r
- "0x%08x: TCP4 port configured\r\n",\r
- pTcp4Protocol ));\r
-\r
- //\r
- // Connect to the remote TCP port\r
- //\r
- Status = pTcp4Protocol->Connect ( pTcp4Protocol,\r
- &Tcp4ConnectToken );\r
- if ( EFI_ERROR ( Status )) {\r
- DEBUG (( DEBUG_ERROR,\r
- "ERROR - Failed to start the connection to the remote system, Status: %r\r\n",\r
- Status ));\r
- break;\r
- }\r
- Status = gBS->WaitForEvent ( 1,\r
- &Tcp4ConnectToken.CompletionToken.Event,\r
- &Index );\r
- if ( EFI_ERROR ( Status )) {\r
- DEBUG (( DEBUG_ERROR,\r
- "ERROR - Failed to wait for the connection, Status: %r\r\n",\r
- Status ));\r
- break;\r
- }\r
- Status = Tcp4ConnectToken.CompletionToken.Status;\r
- if ( EFI_ERROR ( Status )) {\r
- DEBUG (( DEBUG_WARN,\r
- "WARNING - Failed to connect to the remote system, Status: %r\r\n",\r
- Status ));\r
- break;\r
- }\r
- DEBUG (( DEBUG_INFO,\r
- "0x%08x: TCP4 port connected\r\n",\r
- pTcp4Protocol ));\r
- bTcp4Connected = TRUE;\r
-\r
- //\r
- // Display the connection\r
- //\r
- pIpAddress = (UINT8 *)&((struct sockaddr_in *)&RemoteHostAddress)->sin_addr.s_addr;\r
- Print ( L"Connected to %d.%d.%d.%d:%d\r\n",\r
- pIpAddress[0],\r
- pIpAddress[1],\r
- pIpAddress[2],\r
- pIpAddress[3],\r
- ntohs ( ((struct sockaddr_in *)&RemoteHostAddress)->sin_port ));\r
- } while ( 0 );\r
-\r
- if ( EFI_ERROR ( Status )) {\r
- //\r
- // Try again\r
- //\r
- Status = EFI_SUCCESS;\r
- }\r
- else {\r
- //\r
- // Semd data until the connection breaks\r
- //\r
- Status = Tcp4Send ( );\r
- }\r
-\r
- //\r
- // Return the operation status\r
- //\r
- return Status;\r
-}\r
-\r
-\r
-/**\r
- Handle the timer callback\r
-\r
- @param [in] Event Event that caused this callback\r
- @param [in] pContext Context for this routine\r
-**/\r
-VOID\r
-EFIAPI\r
-TimerCallback (\r
- IN EFI_EVENT Event,\r
- IN VOID * pContext\r
- )\r
-{\r
- UINT32 Average;\r
- UINT64 BitsPerSecond;\r
- UINT32 Index;\r
- UINT64 TotalBytes;\r
-\r
- //\r
- // Notify the other code of the timer tick\r
- //\r
- bTick = TRUE;\r
-\r
- //\r
- // Update the average bytes per second\r
- //\r
- if ( 0 != TotalBytesSent ) {\r
- BytesSent[ In ] = TotalBytesSent;\r
- TotalBytesSent = 0;\r
- In += 1;\r
- if ( DATA_SAMPLES <= In ) {\r
- In = 0;\r
- }\r
-\r
- //\r
- // Separate the samples\r
- //\r
- if ( DATA_SAMPLES == Samples ) {\r
- Print ( L"---------- Stable average ----------\r\n" );\r
- }\r
- Samples += 1;\r
-\r
- //\r
- // Compute the data rate\r
- //\r
- TotalBytes = 0;\r
- for ( Index = 0; DATA_SAMPLES > Index; Index++ ) {\r
- TotalBytes += BytesSent[ Index ];\r
- }\r
- Average = (UINT32)RShiftU64 ( TotalBytes, DATA_SAMPLE_SHIFT );\r
- BitsPerSecond = Average * 8;\r
-\r
- //\r
- // Display the data rate\r
- //\r
- if (( RANGE_SWITCH >> 10 ) > Average ) {\r
- Print ( L"Ave: %d Bytes/Sec, %Ld Bits/sec\r\n",\r
- Average,\r
- BitsPerSecond );\r
- }\r
- else {\r
- BitsPerSecond /= 1000;\r
- if ( RANGE_SWITCH > Average ) {\r
- Print ( L"Ave: %d.%03d KiBytes/Sec, %Ld KBits/sec\r\n",\r
- Average >> 10,\r
- (( Average & 0x3ff ) * 1000 ) >> 10,\r
- BitsPerSecond );\r
- }\r
- else {\r
- BitsPerSecond /= 1000;\r
- Average >>= 10;\r
- if ( RANGE_SWITCH > Average ) {\r
- Print ( L"Ave: %d.%03d MiBytes/Sec, %Ld MBits/sec\r\n",\r
- Average >> 10,\r
- (( Average & 0x3ff ) * 1000 ) >> 10,\r
- BitsPerSecond );\r
- }\r
- else {\r
- BitsPerSecond /= 1000;\r
- Average >>= 10;\r
- if ( RANGE_SWITCH > Average ) {\r
- Print ( L"Ave: %d.%03d GiBytes/Sec, %Ld GBits/sec\r\n",\r
- Average >> 10,\r
- (( Average & 0x3ff ) * 1000 ) >> 10,\r
- BitsPerSecond );\r
- }\r
- else {\r
- BitsPerSecond /= 1000;\r
- Average >>= 10;\r
- if ( RANGE_SWITCH > Average ) {\r
- Print ( L"Ave: %d.%03d TiBytes/Sec, %Ld TBits/sec\r\n",\r
- Average >> 10,\r
- (( Average & 0x3ff ) * 1000 ) >> 10,\r
- BitsPerSecond );\r
- }\r
- else {\r
- BitsPerSecond /= 1000;\r
- Average >>= 10;\r
- Print ( L"Ave: %d.%03d PiBytes/Sec, %Ld PBits/sec\r\n",\r
- Average >> 10,\r
- (( Average & 0x3ff ) * 1000 ) >> 10,\r
- BitsPerSecond );\r
- }\r
- }\r
- }\r
- }\r
- }\r
- }\r
-}\r
-\r
-\r
-/**\r
- Create the timer\r
-\r
- @retval EFI_SUCCESS The timer was successfully created\r
- @retval Other Timer initialization failed\r
-**/\r
-EFI_STATUS\r
-TimerCreate (\r
- )\r
-{\r
- EFI_STATUS Status;\r
-\r
- //\r
- // Create the timer\r
- //\r
- Status = gBS->CreateEvent ( EVT_TIMER | EVT_NOTIFY_SIGNAL,\r
- TPL_DATASOURCE,\r
- TimerCallback,\r
- NULL,\r
- &pTimer );\r
- if ( EFI_ERROR ( Status )) {\r
- DEBUG (( DEBUG_ERROR,\r
- "ERROR - Failed to allocate the timer event, Status: %r\r\n",\r
- Status ));\r
- }\r
- else {\r
- DEBUG (( DEBUG_INFO,\r
- "0x%08x: Timer created\r\n",\r
- pTimer ));\r
- }\r
-\r
- //\r
- // Return the operation status\r
- //\r
- return Status;\r
-}\r
-\r
-\r
-/**\r
- Stop the timer\r
-\r
- @retval EFI_SUCCESS The timer was stopped successfully\r
- @retval Other The timer failed to stop\r
-**/\r
-EFI_STATUS\r
-TimerStop (\r
- )\r
-{\r
- EFI_STATUS Status;\r
-\r
- //\r
- // Assume success\r
- //\r
- Status = EFI_SUCCESS;\r
-\r
- //\r
- // Determine if the timer is running\r
- //\r
- if ( bTimerRunning ) {\r
- //\r
- // Stop the timer\r
- //\r
- Status = gBS->SetTimer ( pTimer,\r
- TimerCancel,\r
- 0 );\r
- if ( EFI_ERROR ( Status )) {\r
- DEBUG (( DEBUG_ERROR,\r
- "ERROR - Failed to stop the timer, Status: %r\r\n",\r
- Status ));\r
- }\r
- else {\r
- //\r
- // Timer timer is now stopped\r
- //\r
- bTimerRunning = FALSE;\r
- DEBUG (( DEBUG_INFO,\r
- "0x%08x: Timer stopped\r\n",\r
- pTimer ));\r
- }\r
- }\r
-\r
- //\r
- // Return the operation status\r
- //\r
- return Status;\r
-}\r
-\r
-\r
-/**\r
- Start the timer\r
-\r
- @param [in] Milliseconds The number of milliseconds between timer callbacks\r
-\r
- @retval EFI_SUCCESS The timer was successfully created\r
- @retval Other Timer initialization failed\r
-**/\r
-EFI_STATUS\r
-TimerStart (\r
- UINTN Milliseconds\r
- )\r
-{\r
- EFI_STATUS Status;\r
- UINT64 TimeDelay;\r
-\r
- //\r
- // Stop the timer if necessary\r
- //\r
- Status = EFI_SUCCESS;\r
- if ( bTimerRunning ) {\r
- Status = TimerStop ( );\r
- }\r
- if ( !EFI_ERROR ( Status )) {\r
- //\r
- // Compute the new delay\r
- //\r
- TimeDelay = Milliseconds;\r
- TimeDelay *= 1000 * 10;\r
-\r
- //\r
- // Start the timer\r
- //\r
- Status = gBS->SetTimer ( pTimer,\r
- TimerPeriodic,\r
- TimeDelay );\r
- if ( EFI_ERROR ( Status )) {\r
- DEBUG (( DEBUG_ERROR,\r
- "ERROR - Failed to start the timer, Status: %r\r\n",\r
- Status ));\r
- }\r
- else {\r
- //\r
- // The timer is now running\r
- //\r
- bTimerRunning = TRUE;\r
- DEBUG (( DEBUG_INFO,\r
- "0x%08x: Timer running\r\n",\r
- pTimer ));\r
- }\r
- }\r
-\r
- //\r
- // Return the operation status\r
- //\r
- return Status;\r
-}\r
-\r
-\r
-/**\r
- Destroy the timer\r
-\r
- @retval EFI_SUCCESS The timer was destroyed successfully\r
- @retval Other Failed to destroy the timer\r
-**/\r
-EFI_STATUS\r
-TimerDestroy (\r
- )\r
-{\r
- EFI_STATUS Status;\r
-\r
- //\r
- // Assume success\r
- //\r
- Status = EFI_SUCCESS;\r
-\r
- //\r
- // Determine if the timer is running\r
- //\r
- if ( bTimerRunning ) {\r
- //\r
- // Stop the timer\r
- //\r
- Status = TimerStop ( );\r
- }\r
- if (( !EFI_ERROR ( Status )) && ( NULL != pTimer )) {\r
- //\r
- // Done with this timer\r
- //\r
- Status = gBS->CloseEvent ( pTimer );\r
- if ( EFI_ERROR ( Status )) {\r
- DEBUG (( DEBUG_ERROR,\r
- "ERROR - Failed to free the timer event, Status: %r\r\n",\r
- Status ));\r
- }\r
- else {\r
- DEBUG (( DEBUG_INFO,\r
- "0x%08x: Timer Destroyed\r\n",\r
- pTimer ));\r
- pTimer = NULL;\r
- }\r
- }\r
-\r
- //\r
- // Return the operation status\r
- //\r
- return Status;\r
-}\r
-\r
-\r
-/**\r
- Send data to the DataSink program to test a network's bandwidth.\r
-\r
- @param [in] Argc The number of arguments\r
- @param [in] Argv The argument value array\r
-\r
- @retval 0 The application exited normally.\r
- @retval Other An error occurred.\r
-**/\r
-int\r
-main (\r
- IN int Argc,\r
- IN char **Argv\r
- )\r
-{\r
- EFI_STATUS (* pClose) ();\r
- EFI_STATUS (* pOpen) ();\r
- EFI_STATUS Status;\r
-\r
- DEBUG (( DEBUG_INFO,\r
- "DataSource starting\r\n" ));\r
-\r
- //\r
- // Validate the command line\r
- //\r
- if ( 2 > Argc ) {\r
- Print ( L"%s <remote IP address> [Use TCP]\r\n", Argv[0] );\r
- return -1;\r
- }\r
-\r
- //\r
- // Determine if TCP should be used\r
- //\r
- bTcp4 = (BOOLEAN)( 2 < Argc );\r
-\r
- //\r
- // Determine the support routines\r
- //\r
- if ( bTcp4 ) {\r
- pOpen = Tcp4Open;\r
- pClose = Tcp4Close;\r
- bTcp4Connecting = TRUE;\r
- }\r
- else {\r
- pOpen = SocketOpen;\r
- pClose = SocketClose;\r
- }\r
-\r
- //\r
- // Use for/break instead of goto\r
- //\r
- for ( ; ; ) {\r
- //\r
- // No bytes sent so far\r
- //\r
- TotalBytesSent = 0;\r
- Samples = 0;\r
- memset ( &BytesSent, 0, sizeof ( BytesSent ));\r
-\r
- //\r
- // Get the IP address\r
- //\r
- pRemoteHost = Argv[1];\r
- Status = IpAddress ( );\r
- if ( EFI_ERROR ( Status )) {\r
- break;\r
- }\r
-\r
- //\r
- // Create the timer\r
- //\r
- bTick = TRUE;\r
- Status = TimerCreate ( );\r
- if ( EFI_ERROR ( Status )) {\r
- break;\r
- }\r
-\r
- //\r
- // Loop forever abusing the specified system\r
- //\r
- do {\r
- //\r
- // Start a timer to perform connection polling and display updates\r
- //\r
- Status = TimerStart ( 2 * 1000 );\r
- if ( EFI_ERROR ( Status )) {\r
- break;\r
- }\r
-\r
- //\r
- // Open the network connection and send the data\r
- //\r
- Status = pOpen ( );\r
- if ( EFI_ERROR ( Status )) {\r
- break;\r
- }\r
-\r
- //\r
- // Done with the network connection\r
- //\r
- Status = pClose ( );\r
- } while ( !EFI_ERROR ( Status ));\r
-\r
- //\r
- // Close the network connection if necessary\r
- //\r
- pClose ( );\r
-\r
- //\r
- // All done\r
- //\r
- break;\r
- }\r
-\r
- //\r
- // Stop the timer if necessary\r
- //\r
- TimerStop ( );\r
- TimerDestroy ( );\r
-\r
- //\r
- // Return the operation status\r
- //\r
- DEBUG (( DEBUG_INFO,\r
- "DataSource exiting, Status: %r\r\n",\r
- Status ));\r
- return Status;\r
-}\r