Fix the errors detected by the GCC compiler:
[mirror_edk2.git] / AppPkg / Applications / Sockets / DataSource / DataSource.c
index 9add3f24e7b7c89c5dc1e4aae720aa592a25ad83..6ca3b587e01237b8f25f9084de22eea1b6fbbca8 100644 (file)
 #include <sys/poll.h>\r
 #include <sys/socket.h>\r
 \r
+#include <stdio.h>\r
+#include <string.h>\r
 \r
-#define RANGE_SWITCH                2048  ///<  Switch display ranges\r
-#define DATA_RATE_UPDATE_SHIFT      2     ///<  2n seconds between updates\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
@@ -74,17 +79,17 @@ EFI_EVENT pTimer;
 //\r
 //  Remote IP Address Data\r
 //\r
-struct sockaddr_in RemoteHostAddress;\r
+struct sockaddr_in6 RemoteHostAddress;\r
 CHAR8 * pRemoteHost;\r
 \r
 //\r
 //  Traffic Data\r
 //\r
 UINT64 TotalBytesSent;\r
-UINT64 PreviousBytes;\r
-UINT64 AverageBytes;\r
-UINT64 Samples;\r
-UINT8 Buffer [ DATA_BUFFER_SIZE ];\r
+UINT32 In;\r
+UINT32 Samples;\r
+UINT64 BytesSent[ DATA_SAMPLES ];\r
+UINT8 Buffer[ DATA_BUFFER_SIZE ];\r
 \r
 \r
 //\r
@@ -146,8 +151,7 @@ GetDigit (
   //  Walk the digits\r
   //\r
   Value = 0;\r
-  while (( '0' <= *pDigit ) && ( '9' >= *pDigit ))\r
-  {\r
+  while (( '0' <= *pDigit ) && ( '9' >= *pDigit )) {\r
     //\r
     //  Make room for the new least significant digit\r
     //\r
@@ -186,48 +190,124 @@ EFI_STATUS
 IpAddress (\r
   )\r
 {\r
-  CHAR8 * pSeparator;\r
-  INT32 RemoteAddress;\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
-  pSeparator = GetDigit ( pRemoteHost, &Value1 );\r
-  if (( 255 >= Value1 ) && ( '.' == *pSeparator )) {\r
-    pSeparator = GetDigit ( ++pSeparator, &Value2 );\r
-    if (( 255 >= Value2 ) && ( '.' == *pSeparator )) {\r
-      pSeparator = GetDigit ( ++pSeparator, &Value3 );\r
-      if (( 255 >= Value3 ) && ( '.' == *pSeparator )) {\r
-        pSeparator = GetDigit ( ++pSeparator, &Value4 );\r
-        if (( 255 >= Value4 ) && ( 0 == *pSeparator )) {\r
-          RemoteAddress = Value1\r
-                        | ( Value2 << 8 )\r
-                        | ( Value3 << 16 )\r
-                        | ( Value4 << 24 );\r
-          RemoteHostAddress.sin_addr.s_addr = (UINT32) RemoteAddress;\r
-          Status = EFI_SUCCESS;\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
-      }\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
-  if ( EFI_ERROR ( Status )) {\r
-    Print ( L"Invalid digit detected: %d\r\n", *pSeparator );\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
@@ -291,19 +371,43 @@ SocketConnect (
   )\r
 {\r
   int ConnectStatus;\r
-  UINT32 RemoteAddress;\r
+  struct sockaddr_in * pRemoteAddress4;\r
+  struct sockaddr_in6 * pRemoteAddress6;\r
   EFI_STATUS Status;\r
 \r
   //\r
   //  Display the connecting message\r
   //\r
-  RemoteAddress = RemoteHostAddress.sin_addr.s_addr;\r
-  Print ( L"Connecting to remote system %d.%d.%d.%d:%d\r\n",\r
-          RemoteAddress & 0xff,\r
-          ( RemoteAddress >> 8 ) & 0xff,\r
-          ( RemoteAddress >> 16 ) & 0xff,\r
-          ( RemoteAddress >> 24 ) & 0xff,\r
-          htons ( RemoteHostAddress.sin_port ));\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
+            htons ( 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
+            htons ( pRemoteAddress6->sin6_port ));\r
+  }\r
 \r
   //\r
   //  Connect to the remote system\r
@@ -313,7 +417,7 @@ SocketConnect (
     //\r
     //  Check for user stop request\r
     //\r
-    while ( ! bTick ) {\r
+    while ( !bTick ) {\r
       Status = ControlCCheck ( );\r
       if ( EFI_ERROR ( Status )) {\r
         break;\r
@@ -328,15 +432,37 @@ SocketConnect (
     //  Connect to the remote system\r
     //\r
     ConnectStatus = connect ( Socket,\r
-                              (struct sockaddr *) &RemoteHostAddress,\r
-                              RemoteHostAddress.sin_len );\r
+                              (struct sockaddr *)pRemoteAddress6,\r
+                              pRemoteAddress6->sin6_len );\r
     if ( -1 != ConnectStatus ) {\r
-      Print ( L"Connected to remote system %d.%d.%d.%d:%d\r\n",\r
-              RemoteAddress & 0xff,\r
-              ( RemoteAddress >> 8 ) & 0xff,\r
-              ( RemoteAddress >> 16 ) & 0xff,\r
-              ( RemoteAddress >> 24 ) & 0xff,\r
-              htons ( RemoteHostAddress.sin_port ));\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
+                htons ( 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
+                htons ( pRemoteAddress6->sin6_port ));\r
+      }\r
     }\r
     else {\r
       //\r
@@ -359,11 +485,14 @@ SocketConnect (
 /**\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
@@ -385,7 +514,7 @@ SocketNew (
     //\r
     //  Attempt to create the socket\r
     //\r
-    Socket = socket ( AF_INET,\r
+    Socket = socket ( Family,\r
                       SOCK_STREAM,\r
                       IPPROTO_TCP );\r
     if ( -1 != Socket ) {\r
@@ -420,7 +549,7 @@ SocketSend (
   //\r
   //  Restart the timer\r
   //\r
-  TimerStart ( 1000 << DATA_RATE_UPDATE_SHIFT );\r
+  TimerStart ( 1 * 1000 );\r
 \r
   //\r
   //  Loop until the connection breaks or the user stops\r
@@ -494,12 +623,11 @@ SocketOpen (
   //\r
   //  Use do/while and break instead of goto\r
   //\r
-  do\r
-  {\r
+  do {\r
     //\r
     //  Wait for the network layer to initialize\r
     //\r
-    Status = SocketNew ( );\r
+    Status = SocketNew ( RemoteHostAddress.sin6_family );\r
     if ( EFI_ERROR ( Status )) {\r
       break;\r
     }\r
@@ -586,13 +714,13 @@ Tcp4Close (
           //\r
           //  Display the port closed message\r
           //\r
-          pIpAddress = (UINT8 *)&RemoteHostAddress.sin_addr.s_addr;\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
-                  htons ( RemoteHostAddress.sin_port ));\r
+                  htons ( ((struct sockaddr_in *)&RemoteHostAddress)->sin_port ));\r
         }\r
       }\r
     }\r
@@ -788,20 +916,20 @@ Tcp4Locate (
     //  Display the connecting message\r
     //\r
     if ( bTcp4Connecting ) {\r
-      pIpAddress = (UINT8 *)&RemoteHostAddress.sin_addr.s_addr;\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
-              htons ( RemoteHostAddress.sin_port ));\r
+              htons ( ((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
+    Tcp4Controller = pHandles[ Tcp4Index++ ];\r
     Status = gBS->OpenProtocol (\r
                     Tcp4Controller,\r
                     &gEfiTcp4ServiceBindingProtocolGuid,\r
@@ -887,7 +1015,7 @@ Tcp4Send (
   //\r
   //  Restart the timer\r
   //\r
-  TimerStart ( 1000 << DATA_RATE_UPDATE_SHIFT );\r
+  TimerStart ( 1 * 1000 );\r
 \r
   //\r
   //  Initialize the packet\r
@@ -1097,11 +1225,11 @@ Tcp4Open (
     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)  RemoteHostAddress.sin_addr.s_addr;\r
-    Tcp4ConfigData.AccessPoint.RemoteAddress.Addr[1] = (UINT8)( RemoteHostAddress.sin_addr.s_addr >> 8 );\r
-    Tcp4ConfigData.AccessPoint.RemoteAddress.Addr[2] = (UINT8)( RemoteHostAddress.sin_addr.s_addr >> 16 );\r
-    Tcp4ConfigData.AccessPoint.RemoteAddress.Addr[3] = (UINT8)( RemoteHostAddress.sin_addr.s_addr >> 24 );\r
-    Tcp4ConfigData.AccessPoint.RemotePort = RemoteHostAddress.sin_port;\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 = ((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
@@ -1154,13 +1282,13 @@ Tcp4Open (
     //\r
     //  Display the connection\r
     //\r
-    pIpAddress = (UINT8 *)&RemoteHostAddress.sin_addr.s_addr;\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
-            htons ( RemoteHostAddress.sin_port ));\r
+            htons ( ((struct sockaddr_in *)&RemoteHostAddress)->sin_port ));\r
   } while ( 0 );\r
 \r
   if ( EFI_ERROR ( Status )) {\r
@@ -1190,15 +1318,16 @@ Tcp4Open (
   @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
-  UINT64 BytesSent;\r
-  UINT64 DeltaBytes;\r
-  UINT32 Delta;\r
-  UINT64 Average;\r
+  UINT32 Average;\r
+  UINT64 BitsPerSecond;\r
+  UINT32 Index;\r
+  UINT64 TotalBytes;\r
 \r
   //\r
   //  Notify the other code of the timer tick\r
@@ -1208,65 +1337,82 @@ TimerCallback (
   //\r
   //  Update the average bytes per second\r
   //\r
-  BytesSent = TotalBytesSent;\r
-  if ( 0 != BytesSent ) {\r
-    DeltaBytes = AverageBytes >> AVERAGE_SHIFT_COUNT;\r
-    AverageBytes -= DeltaBytes;\r
-    DeltaBytes = BytesSent - PreviousBytes;\r
-    PreviousBytes = BytesSent;\r
-    AverageBytes += DeltaBytes;\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 (( 2 << AVERAGE_SHIFT_COUNT ) == Samples ) {\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
-    Delta = (UINT32)( DeltaBytes >> DATA_RATE_UPDATE_SHIFT );\r
-    Average = AverageBytes >> ( AVERAGE_SHIFT_COUNT + DATA_RATE_UPDATE_SHIFT );\r
-    if ( Average < RANGE_SWITCH ) {\r
-      Print ( L"%d Bytes/sec, Ave: %d Bytes/Sec\r\n",\r
-              Delta,\r
-              (UINT32) Average );\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
-      Average >>= 10;\r
-      if ( Average < RANGE_SWITCH ) {\r
-        Print ( L"%d Bytes/sec, Ave: %d KiBytes/Sec\r\n",\r
-                Delta,\r
-                (UINT32) Average );\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 ( Average < RANGE_SWITCH ) {\r
-          Print ( L"%d Bytes/sec, Ave: %d MiBytes/Sec\r\n",\r
-                  Delta,\r
-                  (UINT32) Average );\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 ( Average < RANGE_SWITCH ) {\r
-            Print ( L"%d Bytes/sec, Ave: %d GiBytes/Sec\r\n",\r
-                    Delta,\r
-                    (UINT32) Average );\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 ( Average < RANGE_SWITCH ) {\r
-              Print ( L"%d Bytes/sec, Ave: %d TiBytes/Sec\r\n",\r
-                      Delta,\r
-                      Average );\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"%d Bytes/sec, Ave: %d PiBytes/Sec\r\n",\r
-                      Delta,\r
-                      (UINT32) Average );\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
@@ -1499,12 +1645,15 @@ main (
   //\r
   //  Validate the command line\r
   //\r
-  if ( 2 != Argc ) {\r
-    Print ( L"%s  <remote IP address>\r\n", Argv[0] );\r
+  if ( 2 > Argc ) {\r
+    Print ( L"%s  <remote IP address> [Use TCP]\r\n", Argv[0] );\r
     return -1;\r
   }\r
 \r
-bTcp4 = TRUE;\r
+  //\r
+  //  Determine if TCP should be used\r
+  //\r
+  bTcp4 = (BOOLEAN)( 2 < Argc );\r
 \r
   //\r
   //  Determine the support routines\r
@@ -1522,32 +1671,18 @@ bTcp4 = TRUE;
   //\r
   //  Use for/break instead of goto\r
   //\r
-  for ( ; ; )\r
-  {\r
+  for ( ; ; ) {\r
     //\r
     //  No bytes sent so far\r
     //\r
     TotalBytesSent = 0;\r
-    AverageBytes = 0;\r
-    PreviousBytes = 0;\r
     Samples = 0;\r
-\r
-    //\r
-    //  Get the port number\r
-    //\r
-    ZeroMem ( &RemoteHostAddress, sizeof ( RemoteHostAddress ));\r
-    RemoteHostAddress.sin_len = sizeof ( RemoteHostAddress );\r
-    RemoteHostAddress.sin_family = AF_INET;\r
-    RemoteHostAddress.sin_port = htons ( PcdGet16 ( DataSource_Port ));\r
-\r
-Print ( L"Argc: %d\r\n", Argc);\r
-Print ( L"Argv[0]: %a\r\n", Argv[0]);\r
-Print ( L"Argv[1]: %a\r\n", Argv[1]);\r
+    memset ( &BytesSent, 0, sizeof ( BytesSent ));\r
 \r
     //\r
     //  Get the IP address\r
     //\r
-    pRemoteHost = Argv [1];\r
+    pRemoteHost = Argv[1];\r
     Status = IpAddress ( );\r
     if ( EFI_ERROR ( Status )) {\r
       break;\r