]> git.proxmox.com Git - mirror_edk2.git/blobdiff - AppPkg/Applications/Sockets/DataSource/DataSource.c
Merged socket development branch:
[mirror_edk2.git] / AppPkg / Applications / Sockets / DataSource / DataSource.c
index 98a0c9f1209db132fa5d40b47ce5e139f746ccdc..31c38950a640ce3dd042be8a538fc7f9abd59577 100644 (file)
 #include <sys/poll.h>\r
 #include <sys/socket.h>\r
 \r
+#include <stdio.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,16 +78,16 @@ 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
+UINT32 In;\r
+UINT32 Samples;\r
+UINT64 BytesSent[ DATA_SAMPLES ];\r
 UINT8 Buffer[ DATA_BUFFER_SIZE ];\r
 \r
 \r
@@ -185,48 +189,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
@@ -290,19 +370,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
@@ -327,15 +431,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
@@ -358,11 +484,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
@@ -384,7 +513,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
@@ -419,7 +548,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
@@ -497,7 +626,7 @@ SocketOpen (
     //\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
@@ -584,13 +713,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
@@ -786,13 +915,13 @@ 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
@@ -885,7 +1014,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
@@ -1095,11 +1224,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
@@ -1152,13 +1281,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
@@ -1193,10 +1322,10 @@ TimerCallback (
   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
@@ -1206,65 +1335,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
@@ -1528,17 +1674,8 @@ main (
     //  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
+    memset ( &BytesSent, 0, sizeof ( BytesSent ));\r
 \r
     //\r
     //  Get the IP address\r