Home | History | Annotate | Download | only in DataSink
      1 /** @file
      2   Data source for network testing.
      3 
      4   Copyright (c) 2011-2012, Intel Corporation
      5   All rights reserved. This program and the accompanying materials
      6   are licensed and made available under the terms and conditions of the BSD License
      7   which accompanies this distribution.  The full text of the license may be found at
      8   http://opensource.org/licenses/bsd-license.php
      9 
     10   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     11   WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     12 
     13 **/
     14 
     15 #include <errno.h>
     16 #include <Uefi.h>
     17 
     18 #include <Library/BaseMemoryLib.h>
     19 #include <Library/DebugLib.h>
     20 #include <Library/PcdLib.h>
     21 #include <Library/UefiBootServicesTableLib.h>
     22 #include <Library/UefiLib.h>
     23 
     24 #include <netinet/in.h>
     25 
     26 #include <sys/EfiSysCall.h>
     27 #include <sys/poll.h>
     28 #include <sys/socket.h>
     29 
     30 
     31 #define DATA_SAMPLE_SHIFT           5       ///<  Shift for number of samples
     32 #define MAX_CONNECTIONS       ( 1 + 16 )    ///<  Maximum number of client connections
     33 #define RANGE_SWITCH        ( 1024 * 1024 ) ///<  Switch display ranges
     34 #define DATA_RATE_UPDATE_SHIFT      2       ///<  2n seconds between updates
     35 #define AVERAGE_SHIFT_COUNT ( 6 - DATA_RATE_UPDATE_SHIFT )  ///<  2n samples in average
     36 #define DATA_SAMPLES        ( 1 << DATA_SAMPLE_SHIFT )      ///<  Number of samples
     37 
     38 #define TPL_DATASINK        TPL_CALLBACK  ///<  Synchronization TPL
     39 
     40 #define PACKET_SIZE                 1448  ///<  Size of data packets
     41 #define DATA_BUFFER_SIZE    (( 65536 / PACKET_SIZE ) * PACKET_SIZE )  ///<  Buffer size in bytes
     42 
     43 typedef struct _DT_PORT {
     44   UINT64 BytesTotal;
     45   struct sockaddr_in6 IpAddress;
     46   UINT32 In;
     47   UINT32 Samples;
     48   UINT64 BytesReceived[ DATA_SAMPLES ];
     49 } DT_PORT;
     50 
     51 volatile BOOLEAN bTick;
     52 BOOLEAN bTimerRunning;
     53 struct sockaddr_in6 LocalAddress;
     54 EFI_EVENT pTimer;
     55 int ListenSocket;
     56 UINT8 Buffer[ DATA_BUFFER_SIZE ];
     57 struct pollfd PollFd[ MAX_CONNECTIONS ];
     58 DT_PORT Port[ MAX_CONNECTIONS ];
     59 nfds_t MaxPort;
     60 
     61 
     62 //
     63 //  Forward routine declarations
     64 //
     65 EFI_STATUS TimerStart ( UINTN Milliseconds );
     66 
     67 
     68 /**
     69   Check for control C entered at console
     70 
     71   @retval  EFI_SUCCESS  Control C not entered
     72   @retval  EFI_ABORTED  Control C entered
     73 **/
     74 EFI_STATUS
     75 ControlCCheck (
     76   )
     77 {
     78   EFI_STATUS Status;
     79 
     80   //
     81   //  Assume no user intervention
     82   //
     83   Status = EFI_SUCCESS;
     84 
     85   //
     86   //  Display user stop request
     87   //
     88   if ( EFI_ERROR ( Status )) {
     89     DEBUG (( DEBUG_INFO,
     90               "User stop request!\r\n" ));
     91   }
     92 
     93   //
     94   //  Return the check status
     95   //
     96   return Status;
     97 }
     98 
     99 
    100 /**
    101   Accept a socket connection
    102 
    103   @retval  EFI_SUCCESS      The application is running normally
    104   @retval  EFI_NOT_STARTED  Error with the listen socket
    105   @retval  Other            The user stopped the application
    106 **/
    107 EFI_STATUS
    108 SocketAccept (
    109   )
    110 {
    111   INT32 SocketStatus;
    112   EFI_STATUS Status;
    113   INTN Index;
    114 
    115   //
    116   //  Assume failure
    117   //
    118   Status = EFI_DEVICE_ERROR;
    119 
    120   //
    121   //  Bind to the local address
    122   //
    123   SocketStatus = bind ( ListenSocket,
    124                         (struct sockaddr *) &LocalAddress,
    125                         LocalAddress.sin6_len );
    126   if ( 0 == SocketStatus ) {
    127     //
    128     //  Start listening on the local socket
    129     //
    130     SocketStatus = listen ( ListenSocket, 5 );
    131     if ( 0 == SocketStatus ) {
    132       //
    133       //  Local socket in the listen state
    134       //
    135       Status = EFI_SUCCESS;
    136 
    137       //
    138       //  Allocate a port
    139       //
    140       Index = MaxPort++;
    141       PollFd[ Index ].fd = ListenSocket;
    142       PollFd[ Index ].events = POLLRDNORM | POLLHUP;
    143       PollFd[ Index ].revents = 0;
    144       ZeroMem ( &Port[ Index ], sizeof ( Port[ Index ]));
    145     }
    146   }
    147 
    148   //
    149   //  Return the operation status
    150   //
    151   return Status;
    152 }
    153 
    154 
    155 /**
    156   Close the socket
    157 
    158   @retval  EFI_SUCCESS  The application is running normally
    159   @retval  Other        The user stopped the application
    160 **/
    161 EFI_STATUS
    162 SocketClose (
    163   )
    164 {
    165   INT32 CloseStatus;
    166   EFI_STATUS Status;
    167 
    168   //
    169   //  Determine if the socket is open
    170   //
    171   Status = EFI_DEVICE_ERROR;
    172   if ( -1 != ListenSocket ) {
    173     //
    174     //  Attempt to close the socket
    175     //
    176     CloseStatus = close ( ListenSocket );
    177     if ( 0 == CloseStatus ) {
    178       DEBUG (( DEBUG_INFO,
    179                 "0x%08x: Socket closed\r\n",
    180                 ListenSocket ));
    181       ListenSocket = -1;
    182       Status = EFI_SUCCESS;
    183     }
    184     else {
    185       DEBUG (( DEBUG_ERROR,
    186                 "ERROR: Failed to close socket, errno: %d\r\n",
    187                 errno ));
    188     }
    189   }
    190 
    191   //
    192   //  Return the operation status
    193   //
    194   return Status;
    195 }
    196 
    197 
    198 /**
    199   Create the socket
    200 
    201   @param [in] Family    Network family, AF_INET or AF_INET6
    202 
    203   @retval  EFI_SUCCESS  The application is running normally
    204   @retval  Other        The user stopped the application
    205 **/
    206 EFI_STATUS
    207 SocketNew (
    208   sa_family_t Family
    209   )
    210 {
    211   EFI_STATUS Status;
    212 
    213   //
    214   //  Get the port number
    215   //
    216   ZeroMem ( &LocalAddress, sizeof ( LocalAddress ));
    217   LocalAddress.sin6_len = sizeof ( LocalAddress );
    218   LocalAddress.sin6_family = Family;
    219   LocalAddress.sin6_port = htons ( PcdGet16 ( DataSource_Port ));
    220 
    221   //
    222   //  Loop creating the socket
    223   //
    224   DEBUG (( DEBUG_INFO,
    225             "Creating the socket\r\n" ));
    226 
    227   //
    228   //  Check for user stop request
    229   //
    230   Status = ControlCCheck ( );
    231   if ( !EFI_ERROR ( Status )) {
    232     //
    233     //  Attempt to create the socket
    234     //
    235     ListenSocket = socket ( LocalAddress.sin6_family,
    236                             SOCK_STREAM,
    237                             IPPROTO_TCP );
    238     if ( -1 != ListenSocket ) {
    239       DEBUG (( DEBUG_INFO,
    240                 "0x%08x: Socket created\r\n",
    241                 ListenSocket ));
    242     }
    243     else {
    244       Status = EFI_NOT_STARTED;
    245     }
    246   }
    247 
    248   //
    249   //  Return the operation status
    250   //
    251   return Status;
    252 }
    253 
    254 
    255 /**
    256   Poll the socket for more work
    257 
    258   @retval  EFI_SUCCESS      The application is running normally
    259   @retval  EFI_NOT_STARTED  Listen socket error
    260   @retval  Other            The user stopped the application
    261 **/
    262 EFI_STATUS
    263 SocketPoll (
    264   )
    265 {
    266   BOOLEAN bRemoveSocket;
    267   BOOLEAN bListenError;
    268   size_t BytesReceived;
    269   int CloseStatus;
    270   nfds_t Entry;
    271   INTN EntryPrevious;
    272   int FdCount;
    273   nfds_t Index;
    274   socklen_t LengthInBytes;
    275   struct sockaddr_in * pPortIpAddress4;
    276   struct sockaddr_in6 * pPortIpAddress6;
    277   struct sockaddr_in * pRemoteAddress4;
    278   struct sockaddr_in6 * pRemoteAddress6;
    279   struct sockaddr_in6 RemoteAddress;
    280   int Socket;
    281   EFI_STATUS Status;
    282   EFI_TPL TplPrevious;
    283 
    284   //
    285   //  Check for control-C
    286   //
    287   pRemoteAddress4 = (struct sockaddr_in *)&RemoteAddress;
    288   pRemoteAddress6 = (struct sockaddr_in6 *)&RemoteAddress;
    289   bListenError = FALSE;
    290   Status = ControlCCheck ( );
    291   if ( !EFI_ERROR ( Status )) {
    292     //
    293     //  Poll the sockets
    294     //
    295     FdCount = poll ( &PollFd[0],
    296                      MaxPort,
    297                      0 );
    298     if ( -1 == FdCount ) {
    299       //
    300       //  Poll error
    301       //
    302       DEBUG (( DEBUG_ERROR,
    303                 "ERROR - Poll error, errno: %d\r\n",
    304                 errno ));
    305       Status = EFI_DEVICE_ERROR;
    306     }
    307     else {
    308       //
    309       //  Process the poll output
    310       //
    311       Index = 0;
    312       while ( FdCount ) {
    313         bRemoveSocket = FALSE;
    314 
    315         //
    316         //  Account for this descriptor
    317         //
    318         pPortIpAddress4 = (struct sockaddr_in *)&Port[ Index ].IpAddress;
    319         pPortIpAddress6 = (struct sockaddr_in6 *)&Port[ Index ].IpAddress;
    320         if ( 0 != PollFd[ Index ].revents ) {
    321           FdCount -= 1;
    322         }
    323 
    324         //
    325         //  Check for a broken connection
    326         //
    327         if ( 0 != ( PollFd[ Index ].revents & POLLHUP )) {
    328           bRemoveSocket = TRUE;
    329           if ( ListenSocket == PollFd[ Index ].fd ) {
    330             bListenError = TRUE;
    331             DEBUG (( DEBUG_ERROR,
    332                       "ERROR - Network closed on listen socket, errno: %d\r\n",
    333                       errno ));
    334           }
    335           else {
    336             if ( AF_INET == pPortIpAddress4->sin_family ) {
    337               DEBUG (( DEBUG_ERROR,
    338                         "ERROR - Network closed on socket %d.%d.%d.%d:%d, errno: %d\r\n",
    339                         pPortIpAddress4->sin_addr.s_addr & 0xff,
    340                         ( pPortIpAddress4->sin_addr.s_addr >> 8 ) & 0xff,
    341                         ( pPortIpAddress4->sin_addr.s_addr >> 16 ) & 0xff,
    342                         ( pPortIpAddress4->sin_addr.s_addr >> 24 ) & 0xff,
    343                         ntohs ( pPortIpAddress4->sin_port ),
    344                         errno ));
    345             }
    346             else {
    347               DEBUG (( DEBUG_ERROR,
    348                         "ERROR - Network closed on socket [%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]:%d, errno: %d\r\n",
    349                         pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 0 ],
    350                         pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 1 ],
    351                         pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 2 ],
    352                         pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 3 ],
    353                         pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 4 ],
    354                         pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 5 ],
    355                         pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 6 ],
    356                         pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 7 ],
    357                         pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 8 ],
    358                         pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 9 ],
    359                         pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 10 ],
    360                         pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 11 ],
    361                         pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 12 ],
    362                         pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 13 ],
    363                         pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 14 ],
    364                         pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 15 ],
    365                         ntohs ( pPortIpAddress6->sin6_port ),
    366                         errno ));
    367             }
    368 
    369             //
    370             //  Close the socket
    371             //
    372             CloseStatus = close ( PollFd[ Index ].fd );
    373             if ( 0 == CloseStatus ) {
    374               bRemoveSocket = TRUE;
    375               if ( AF_INET == pPortIpAddress4->sin_family ) {
    376                 DEBUG (( DEBUG_INFO,
    377                           "0x%08x: Socket closed for %d.%d.%d.%d:%d\r\n",
    378                           PollFd[ Index ].fd,
    379                           pPortIpAddress4->sin_addr.s_addr & 0xff,
    380                           ( pPortIpAddress4->sin_addr.s_addr >> 8 ) & 0xff,
    381                           ( pPortIpAddress4->sin_addr.s_addr >> 16 ) & 0xff,
    382                           ( pPortIpAddress4->sin_addr.s_addr >> 24 ) & 0xff,
    383                           ntohs ( pPortIpAddress4->sin_port )));
    384               }
    385               else {
    386                 DEBUG (( DEBUG_INFO,
    387                           "0x%08x: Socket closed for [%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]:%d\r\n",
    388                           PollFd[ Index ].fd,
    389                           pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 0 ],
    390                           pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 1 ],
    391                           pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 2 ],
    392                           pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 3 ],
    393                           pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 4 ],
    394                           pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 5 ],
    395                           pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 6 ],
    396                           pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 7 ],
    397                           pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 8 ],
    398                           pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 9 ],
    399                           pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 10 ],
    400                           pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 11 ],
    401                           pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 12 ],
    402                           pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 13 ],
    403                           pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 14 ],
    404                           pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 15 ],
    405                           ntohs ( pPortIpAddress6->sin6_port )));
    406               }
    407             }
    408             else {
    409               if ( AF_INET == pPortIpAddress4->sin_family ) {
    410                 DEBUG (( DEBUG_ERROR,
    411                           "ERROR - Failed to close socket 0x%08x for %d.%d.%d.%d:%d, errno: %d\r\n",
    412                           PollFd[ Index ].fd,
    413                           pPortIpAddress4->sin_addr.s_addr & 0xff,
    414                           ( pPortIpAddress4->sin_addr.s_addr >> 8 ) & 0xff,
    415                           ( pPortIpAddress4->sin_addr.s_addr >> 16 ) & 0xff,
    416                           ( pPortIpAddress4->sin_addr.s_addr >> 24 ) & 0xff,
    417                           ntohs ( pPortIpAddress4->sin_port ),
    418                           errno ));
    419               }
    420               else {
    421                 DEBUG (( DEBUG_ERROR,
    422                           "ERROR - Failed to close socket 0x%08x for [%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]:%d, errno: %d\r\n",
    423                           PollFd[ Index ].fd,
    424                           pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 0 ],
    425                           pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 1 ],
    426                           pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 2 ],
    427                           pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 3 ],
    428                           pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 4 ],
    429                           pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 5 ],
    430                           pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 6 ],
    431                           pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 7 ],
    432                           pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 8 ],
    433                           pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 9 ],
    434                           pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 10 ],
    435                           pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 11 ],
    436                           pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 12 ],
    437                           pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 13 ],
    438                           pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 14 ],
    439                           pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 15 ],
    440                           ntohs ( pPortIpAddress6->sin6_port ),
    441                           errno ));
    442               }
    443             }
    444           }
    445         }
    446 
    447         //
    448         //  Check for a connection or read data
    449         //
    450         if ( 0 != ( PollFd[ Index ].revents & POLLRDNORM )) {
    451           //
    452           //  Check for a connection
    453           //
    454           if ( ListenSocket == PollFd[ Index ].fd ) {
    455             //
    456             //  Another client connection was received
    457             //
    458             LengthInBytes = sizeof ( RemoteAddress );
    459             Socket = accept ( ListenSocket,
    460                               (struct sockaddr *) &RemoteAddress,
    461                               &LengthInBytes );
    462             if ( -1 == Socket ) {
    463               //
    464               //  Listen socket error
    465               //
    466               bListenError = TRUE;
    467               bRemoveSocket = TRUE;
    468               DEBUG (( DEBUG_ERROR,
    469                         "ERROR - Listen socket failure, errno: %d\r\n",
    470                         errno ));
    471             }
    472             else {
    473               //
    474               //  Determine if there is room for this connection
    475               //
    476               if (( MAX_CONNECTIONS <= MaxPort )
    477                 || ((( MAX_CONNECTIONS - 1 ) == MaxPort ) && ( -1 == ListenSocket ))) {
    478                 //
    479                 //  Display the connection
    480                 //
    481                 if ( AF_INET == pRemoteAddress4->sin_family ) {
    482                   Print ( L"Rejecting connection to remote system %d.%d.%d.%d:%d\r\n",
    483                           pRemoteAddress4->sin_addr.s_addr & 0xff,
    484                           ( pRemoteAddress4->sin_addr.s_addr >> 8 ) & 0xff,
    485                           ( pRemoteAddress4->sin_addr.s_addr >> 16 ) & 0xff,
    486                           ( pRemoteAddress4->sin_addr.s_addr >> 24 ) & 0xff,
    487                           ntohs ( pRemoteAddress4->sin_port ));
    488                 }
    489                 else {
    490                   Print ( L"Rejecting connection to remote system [%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]:%d\r\n",
    491                           pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 0 ],
    492                           pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 1 ],
    493                           pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 2 ],
    494                           pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 3 ],
    495                           pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 4 ],
    496                           pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 5 ],
    497                           pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 6 ],
    498                           pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 7 ],
    499                           pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 8 ],
    500                           pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 9 ],
    501                           pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 10 ],
    502                           pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 11 ],
    503                           pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 12 ],
    504                           pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 13 ],
    505                           pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 14 ],
    506                           pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 15 ],
    507                           ntohs ( pRemoteAddress6->sin6_port ));
    508                 }
    509 
    510                 //
    511                 //  No room for this connection
    512                 //  Close the connection
    513                 //
    514                 CloseStatus = close ( Socket );
    515                 if ( 0 == CloseStatus ) {
    516                   bRemoveSocket = TRUE;
    517                   if ( AF_INET == pRemoteAddress4->sin_family ) {
    518                     DEBUG (( DEBUG_INFO,
    519                               "0x%08x: Socket closed for %d.%d.%d.%d:%d\r\n",
    520                               PollFd[ Index ].fd,
    521                               pRemoteAddress4->sin_addr.s_addr & 0xff,
    522                               ( pRemoteAddress4->sin_addr.s_addr >> 8 ) & 0xff,
    523                               ( pRemoteAddress4->sin_addr.s_addr >> 16 ) & 0xff,
    524                               ( pRemoteAddress4->sin_addr.s_addr >> 24 ) & 0xff,
    525                               ntohs ( pRemoteAddress4->sin_port )));
    526                   }
    527                   else {
    528                     DEBUG (( DEBUG_INFO,
    529                               "0x%08x: Socket closed for [%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]:%d\r\n",
    530                               PollFd[ Index ].fd,
    531                               pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 0 ],
    532                               pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 1 ],
    533                               pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 2 ],
    534                               pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 3 ],
    535                               pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 4 ],
    536                               pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 5 ],
    537                               pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 6 ],
    538                               pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 7 ],
    539                               pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 8 ],
    540                               pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 9 ],
    541                               pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 10 ],
    542                               pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 11 ],
    543                               pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 12 ],
    544                               pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 13 ],
    545                               pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 14 ],
    546                               pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 15 ],
    547                               ntohs ( pRemoteAddress6->sin6_port )));
    548                   }
    549                 }
    550                 else {
    551                   DEBUG (( DEBUG_ERROR,
    552                             "ERROR - Failed to close socket 0x%08x, errno: %d\r\n",
    553                             PollFd[ Index ].fd,
    554                             errno ));
    555                 }
    556 
    557                 //
    558                 //  Keep the application running
    559                 //  No issue with the listen socket
    560                 //
    561                 Status = EFI_SUCCESS;
    562               }
    563               else {
    564                 //
    565                 //  Display the connection
    566                 //
    567                 if ( AF_INET == pRemoteAddress4->sin_family ) {
    568                   Print ( L"Connected to remote system %d.%d.%d.%d:%d\r\n",
    569                           pRemoteAddress4->sin_addr.s_addr & 0xff,
    570                           ( pRemoteAddress4->sin_addr.s_addr >> 8 ) & 0xff,
    571                           ( pRemoteAddress4->sin_addr.s_addr >> 16 ) & 0xff,
    572                           ( pRemoteAddress4->sin_addr.s_addr >> 24 ) & 0xff,
    573                           ntohs ( pRemoteAddress4->sin_port ));
    574                 }
    575                 else {
    576                   Print ( L"Connected to remote system [%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]:%d\r\n",
    577                           pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 0 ],
    578                           pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 1 ],
    579                           pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 2 ],
    580                           pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 3 ],
    581                           pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 4 ],
    582                           pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 5 ],
    583                           pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 6 ],
    584                           pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 7 ],
    585                           pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 8 ],
    586                           pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 9 ],
    587                           pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 10 ],
    588                           pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 11 ],
    589                           pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 12 ],
    590                           pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 13 ],
    591                           pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 14 ],
    592                           pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 15 ],
    593                           ntohs ( pRemoteAddress6->sin6_port ));
    594                 }
    595 
    596                 //
    597                 //  Allocate the client connection
    598                 //
    599                 Index = MaxPort++;
    600                 ZeroMem ( &Port[ Index ], sizeof ( Port[ Index ]));
    601                 CopyMem ( pPortIpAddress6, pRemoteAddress6, sizeof ( *pRemoteAddress6 ));
    602                 PollFd[ Index ].fd = Socket;
    603                 PollFd[ Index ].events = POLLRDNORM | POLLHUP;
    604                 PollFd[ Index ].revents = 0;
    605               }
    606             }
    607           }
    608           else {
    609             //
    610             //  Data received
    611             //
    612             BytesReceived = read ( PollFd[ Index ].fd,
    613                                    &Buffer,
    614                                    sizeof ( Buffer ));
    615             if ( 0 < BytesReceived ) {
    616               //
    617               //  Display the amount of data received
    618               //
    619               if ( AF_INET == pPortIpAddress4->sin_family ) {
    620                 DEBUG (( DEBUG_INFO,
    621                           "0x%08x: Socket received 0x%08x bytes from %d.%d.%d.%d:%d\r\n",
    622                           PollFd[ Index ].fd,
    623                           BytesReceived,
    624                           pPortIpAddress4->sin_addr.s_addr & 0xff,
    625                           ( pPortIpAddress4->sin_addr.s_addr >> 8 ) & 0xff,
    626                           ( pPortIpAddress4->sin_addr.s_addr >> 16 ) & 0xff,
    627                           ( pPortIpAddress4->sin_addr.s_addr >> 24 ) & 0xff,
    628                           ntohs ( pPortIpAddress4->sin_port )));
    629               }
    630               else {
    631                 DEBUG (( DEBUG_INFO,
    632                           "0x%08x: Socket received 0x%08x bytes from [%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]:%d\r\n",
    633                           PollFd[ Index ].fd,
    634                           BytesReceived,
    635                           pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 0 ],
    636                           pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 1 ],
    637                           pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 2 ],
    638                           pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 3 ],
    639                           pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 4 ],
    640                           pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 5 ],
    641                           pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 6 ],
    642                           pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 7 ],
    643                           pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 8 ],
    644                           pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 9 ],
    645                           pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 10 ],
    646                           pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 11 ],
    647                           pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 12 ],
    648                           pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 13 ],
    649                           pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 14 ],
    650                           pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 15 ],
    651                           ntohs ( pPortIpAddress6->sin6_port )));
    652               }
    653 
    654               //
    655               //  Synchronize with the TimerCallback routine
    656               //
    657               TplPrevious = gBS->RaiseTPL ( TPL_DATASINK );
    658 
    659               //
    660               //  Account for the data received
    661               //
    662               Port[ Index ].BytesTotal += BytesReceived;
    663 
    664               //
    665               //  Release the synchronization with the TimerCallback routine
    666               //
    667               gBS->RestoreTPL ( TplPrevious );
    668             }
    669             else if ( -1 == BytesReceived ) {
    670               //
    671               //  Close the socket
    672               //
    673               if ( AF_INET == pPortIpAddress4->sin_family ) {
    674                 DEBUG (( DEBUG_INFO,
    675                           "ERROR - Receive failure for %d.%d.%d.%d:%d, errno: %d\r\n",
    676                           pPortIpAddress4->sin_addr.s_addr & 0xff,
    677                           ( pPortIpAddress4->sin_addr.s_addr >> 8 ) & 0xff,
    678                           ( pPortIpAddress4->sin_addr.s_addr >> 16 ) & 0xff,
    679                           ( pPortIpAddress4->sin_addr.s_addr >> 24 ) & 0xff,
    680                           ntohs ( pPortIpAddress4->sin_port ),
    681                           errno ));
    682               }
    683               else {
    684                 DEBUG (( DEBUG_INFO,
    685                           "ERROR - Receive failure for [%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]:%d, errno: %d\r\n",
    686                           pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 0 ],
    687                           pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 1 ],
    688                           pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 2 ],
    689                           pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 3 ],
    690                           pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 4 ],
    691                           pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 5 ],
    692                           pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 6 ],
    693                           pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 7 ],
    694                           pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 8 ],
    695                           pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 9 ],
    696                           pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 10 ],
    697                           pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 11 ],
    698                           pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 12 ],
    699                           pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 13 ],
    700                           pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 14 ],
    701                           pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 15 ],
    702                           ntohs ( pPortIpAddress6->sin6_port ),
    703                           errno ));
    704               }
    705               CloseStatus = close ( PollFd[ Index ].fd );
    706               if ( 0 == CloseStatus ) {
    707                 bRemoveSocket = TRUE;
    708                 if ( AF_INET == pPortIpAddress4->sin_family ) {
    709                   DEBUG (( DEBUG_INFO,
    710                             "0x%08x: Socket closed for %d.%d.%d.%d:%d\r\n",
    711                             PollFd[ Index ].fd,
    712                             pPortIpAddress4->sin_addr.s_addr & 0xff,
    713                             ( pPortIpAddress4->sin_addr.s_addr >> 8 ) & 0xff,
    714                             ( pPortIpAddress4->sin_addr.s_addr >> 16 ) & 0xff,
    715                             ( pPortIpAddress4->sin_addr.s_addr >> 24 ) & 0xff,
    716                             ntohs ( pPortIpAddress4->sin_port )));
    717                 }
    718                 else {
    719                   DEBUG (( DEBUG_INFO,
    720                             "0x%08x: Socket closed for [%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]:%d\r\n",
    721                             PollFd[ Index ].fd,
    722                             pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 0 ],
    723                             pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 1 ],
    724                             pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 2 ],
    725                             pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 3 ],
    726                             pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 4 ],
    727                             pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 5 ],
    728                             pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 6 ],
    729                             pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 7 ],
    730                             pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 8 ],
    731                             pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 9 ],
    732                             pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 10 ],
    733                             pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 11 ],
    734                             pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 12 ],
    735                             pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 13 ],
    736                             pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 14 ],
    737                             pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 15 ],
    738                             ntohs ( pPortIpAddress6->sin6_port )));
    739                 }
    740               }
    741               else {
    742                 if ( AF_INET == pPortIpAddress4->sin_family ) {
    743                   DEBUG (( DEBUG_ERROR,
    744                             "ERROR - Failed to close socket 0x%08x for %d.%d.%d.%d:%d, errno: %d\r\n",
    745                             PollFd[ Index ].fd,
    746                             pPortIpAddress4->sin_addr.s_addr & 0xff,
    747                             ( pPortIpAddress4->sin_addr.s_addr >> 8 ) & 0xff,
    748                             ( pPortIpAddress4->sin_addr.s_addr >> 16 ) & 0xff,
    749                             ( pPortIpAddress4->sin_addr.s_addr >> 24 ) & 0xff,
    750                             ntohs ( pPortIpAddress4->sin_port ),
    751                             errno ));
    752                 }
    753                 else {
    754                   DEBUG (( DEBUG_ERROR,
    755                             "ERROR - Failed to close socket 0x%08x for [%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]:%d, errno: %d\r\n",
    756                             PollFd[ Index ].fd,
    757                             pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 0 ],
    758                             pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 1 ],
    759                             pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 2 ],
    760                             pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 3 ],
    761                             pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 4 ],
    762                             pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 5 ],
    763                             pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 6 ],
    764                             pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 7 ],
    765                             pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 8 ],
    766                             pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 9 ],
    767                             pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 10 ],
    768                             pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 11 ],
    769                             pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 12 ],
    770                             pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 13 ],
    771                             pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 14 ],
    772                             pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 15 ],
    773                             ntohs ( pPortIpAddress6->sin6_port ),
    774                             errno ));
    775                 }
    776               }
    777             }
    778 
    779             //
    780             //  Keep the application running
    781             //  No issue with the listen socket
    782             //
    783             Status = EFI_SUCCESS;
    784           }
    785         }
    786 
    787         //
    788         //  Remove the socket if necessary
    789         //
    790         if ( bRemoveSocket ) {
    791           DEBUG (( DEBUG_INFO,
    792                     "0x%08x: Socket removed from polling\r\n",
    793                     PollFd[ Index ].fd ));
    794           MaxPort -= 1;
    795           for ( Entry = Index + 1; MaxPort >= Entry; Entry++ ) {
    796             EntryPrevious = Entry;
    797             CopyMem ( &Port[ EntryPrevious ],
    798                       &Port[ Entry ],
    799                       sizeof ( Port[ Entry ]));
    800             PollFd[ EntryPrevious ].events = PollFd[ Entry ].events;
    801             PollFd[ EntryPrevious ].fd = PollFd[ Entry ].fd;
    802             PollFd[ EntryPrevious ].revents = PollFd[ Entry ].revents;
    803           }
    804           PollFd[ MaxPort ].fd = -1;
    805           Index -= 1;
    806         }
    807 
    808         //
    809         //  Account for this socket
    810         //
    811         Index += 1;
    812       }
    813     }
    814   }
    815 
    816   //
    817   //  Return the listen failure if necessary
    818   //
    819   if (( !EFI_ERROR ( Status )) && bListenError ) {
    820     Status = EFI_NOT_STARTED;
    821   }
    822 
    823   //
    824   //  Return the poll status
    825   //
    826   return Status;
    827 }
    828 
    829 
    830 /**
    831   Handle the timer callback
    832 
    833   @param [in] Event     Event that caused this callback
    834   @param [in] pContext  Context for this routine
    835 **/
    836 VOID
    837 EFIAPI
    838 TimerCallback (
    839   IN EFI_EVENT Event,
    840   IN VOID * pContext
    841   )
    842 {
    843   UINT32 Average;
    844   UINT64 BitsPerSecond;
    845   UINT64 BytesReceived;
    846   UINT32 Count;
    847   nfds_t Index;
    848   UINT64 TotalBytes;
    849 
    850   //
    851   //  Notify the other code of the timer tick
    852   //
    853   bTick = TRUE;
    854 
    855   //
    856   //  Walk the list of ports
    857   //
    858   for ( Index = 0; MaxPort > Index; Index++ ) {
    859     //
    860     //  Determine if any data was received
    861     //
    862     BytesReceived = Port[ Index ].BytesTotal;
    863     if (( ListenSocket != PollFd[ Index ].fd )
    864       && ( 0 != BytesReceived )) {
    865       //
    866       //  Update the received data samples
    867       //
    868       Port[ Index ].BytesTotal = 0;
    869       Port[ Index ].BytesReceived [ Port[ Index ].In ] = BytesReceived;
    870       Port[ Index ].In += 1;
    871       if ( DATA_SAMPLES <= Port[ Index ].In ) {
    872         Port[ Index ].In = 0;
    873       }
    874 
    875       //
    876       //  Separate the samples
    877       //
    878       if ( DATA_SAMPLES == Port[ Index ].Samples ) {
    879         Print ( L"---------- Stable average ----------\r\n" );
    880       }
    881       Port[ Index ].Samples += 1;
    882 
    883       //
    884       //  Compute the data rate
    885       //
    886       TotalBytes = 0;
    887       for ( Count = 0; DATA_SAMPLES > Count; Count++ )
    888       {
    889           TotalBytes += Port[ Index ].BytesReceived[ Count ];
    890       }
    891       Average = (UINT32)RShiftU64 ( TotalBytes, DATA_SAMPLE_SHIFT );
    892       BitsPerSecond = Average * 8;
    893 
    894       //
    895       //  Display the data rate
    896       //
    897       if (( RANGE_SWITCH >> 10 ) > Average ) {
    898         Print ( L"Ave: %d Bytes/Sec, %Ld Bits/sec\r\n",
    899                 Average,
    900                 BitsPerSecond );
    901       }
    902       else {
    903         BitsPerSecond /= 1000;
    904         if ( RANGE_SWITCH > Average ) {
    905           Print ( L"Ave: %d.%03d KiBytes/Sec, %Ld KBits/sec\r\n",
    906                   Average >> 10,
    907                   (( Average & 0x3ff ) * 1000 ) >> 10,
    908                   BitsPerSecond );
    909         }
    910         else {
    911           BitsPerSecond /= 1000;
    912           Average >>= 10;
    913           if ( RANGE_SWITCH > Average ) {
    914             Print ( L"Ave: %d.%03d MiBytes/Sec, %Ld MBits/sec\r\n",
    915                     Average >> 10,
    916                     (( Average & 0x3ff ) * 1000 ) >> 10,
    917                     BitsPerSecond );
    918           }
    919           else {
    920             BitsPerSecond /= 1000;
    921             Average >>= 10;
    922             if ( RANGE_SWITCH > Average ) {
    923               Print ( L"Ave: %d.%03d GiBytes/Sec, %Ld GBits/sec\r\n",
    924                       Average >> 10,
    925                       (( Average & 0x3ff ) * 1000 ) >> 10,
    926                       BitsPerSecond );
    927             }
    928             else {
    929               BitsPerSecond /= 1000;
    930               Average >>= 10;
    931               if ( RANGE_SWITCH > Average ) {
    932                 Print ( L"Ave: %d.%03d TiBytes/Sec, %Ld TBits/sec\r\n",
    933                         Average >> 10,
    934                         (( Average & 0x3ff ) * 1000 ) >> 10,
    935                         BitsPerSecond );
    936               }
    937               else {
    938                 BitsPerSecond /= 1000;
    939                 Average >>= 10;
    940                 Print ( L"Ave: %d.%03d PiBytes/Sec, %Ld PBits/sec\r\n",
    941                         Average >> 10,
    942                         (( Average & 0x3ff ) * 1000 ) >> 10,
    943                         BitsPerSecond );
    944               }
    945             }
    946           }
    947         }
    948       }
    949     }
    950   }
    951 }
    952 
    953 
    954 /**
    955   Create the timer
    956 
    957   @retval  EFI_SUCCESS  The timer was successfully created
    958   @retval  Other        Timer initialization failed
    959 **/
    960 EFI_STATUS
    961 TimerCreate (
    962   )
    963 {
    964   EFI_STATUS Status;
    965 
    966   //
    967   //  Create the timer
    968   //
    969   Status = gBS->CreateEvent ( EVT_TIMER | EVT_NOTIFY_SIGNAL,
    970                               TPL_DATASINK,
    971                               TimerCallback,
    972                               NULL,
    973                               &pTimer );
    974   if ( EFI_ERROR ( Status )) {
    975     DEBUG (( DEBUG_ERROR,
    976               "ERROR - Failed to allocate the timer event, Status: %r\r\n",
    977               Status ));
    978   }
    979   else {
    980     DEBUG (( DEBUG_INFO,
    981               "0x%08x: Timer created\r\n",
    982               pTimer ));
    983   }
    984 
    985   //
    986   //  Return the operation status
    987   //
    988   return Status;
    989 }
    990 
    991 
    992 /**
    993   Stop the timer
    994 
    995   @retval  EFI_SUCCESS  The timer was stopped successfully
    996   @retval  Other        The timer failed to stop
    997 **/
    998 EFI_STATUS
    999 TimerStop (
   1000   )
   1001 {
   1002   EFI_STATUS Status;
   1003 
   1004   //
   1005   //  Assume success
   1006   //
   1007   Status = EFI_SUCCESS;
   1008 
   1009   //
   1010   //  Determine if the timer is running
   1011   //
   1012   if ( bTimerRunning ) {
   1013     //
   1014     //  Stop the timer
   1015     //
   1016     Status = gBS->SetTimer ( pTimer,
   1017                              TimerCancel,
   1018                              0 );
   1019     if ( EFI_ERROR ( Status )) {
   1020       DEBUG (( DEBUG_ERROR,
   1021                 "ERROR - Failed to stop the timer, Status: %r\r\n",
   1022                 Status ));
   1023     }
   1024     else {
   1025       //
   1026       //  Timer timer is now stopped
   1027       //
   1028       bTimerRunning = FALSE;
   1029       DEBUG (( DEBUG_INFO,
   1030                 "0x%08x: Timer stopped\r\n",
   1031                 pTimer ));
   1032     }
   1033   }
   1034 
   1035   //
   1036   //  Return the operation status
   1037   //
   1038   return Status;
   1039 }
   1040 
   1041 
   1042 /**
   1043   Start the timer
   1044 
   1045   @param [in] Milliseconds  The number of milliseconds between timer callbacks
   1046 
   1047   @retval  EFI_SUCCESS  The timer was successfully created
   1048   @retval  Other        Timer initialization failed
   1049 **/
   1050 EFI_STATUS
   1051 TimerStart (
   1052   UINTN Milliseconds
   1053   )
   1054 {
   1055   EFI_STATUS Status;
   1056   UINT64 TimeDelay;
   1057 
   1058   //
   1059   //  Stop the timer if necessary
   1060   //
   1061   Status = EFI_SUCCESS;
   1062   if ( bTimerRunning ) {
   1063     Status = TimerStop ( );
   1064   }
   1065   if ( !EFI_ERROR ( Status )) {
   1066     //
   1067     //  Compute the new delay
   1068     //
   1069     TimeDelay = Milliseconds;
   1070     TimeDelay *= 1000 * 10;
   1071 
   1072     //
   1073     //  Start the timer
   1074     //
   1075     Status = gBS->SetTimer ( pTimer,
   1076                              TimerPeriodic,
   1077                              TimeDelay );
   1078     if ( EFI_ERROR ( Status )) {
   1079       DEBUG (( DEBUG_ERROR,
   1080                 "ERROR - Failed to start the timer, Status: %r\r\n",
   1081                 Status ));
   1082     }
   1083     else {
   1084       //
   1085       //  The timer is now running
   1086       //
   1087       bTimerRunning = TRUE;
   1088       DEBUG (( DEBUG_INFO,
   1089         "0x%08x: Timer running\r\n",
   1090         pTimer ));
   1091     }
   1092   }
   1093 
   1094   //
   1095   //  Return the operation status
   1096   //
   1097   return Status;
   1098 }
   1099 
   1100 
   1101 /**
   1102   Destroy the timer
   1103 
   1104   @retval  EFI_SUCCESS  The timer was destroyed successfully
   1105   @retval  Other        Failed to destroy the timer
   1106 **/
   1107 EFI_STATUS
   1108 TimerDestroy (
   1109   )
   1110 {
   1111   EFI_STATUS Status;
   1112 
   1113   //
   1114   //  Assume success
   1115   //
   1116   Status = EFI_SUCCESS;
   1117 
   1118   //
   1119   //  Determine if the timer is running
   1120   //
   1121   if ( bTimerRunning ) {
   1122     //
   1123     //  Stop the timer
   1124     //
   1125     Status = TimerStop ( );
   1126   }
   1127   if (( !EFI_ERROR ( Status )) && ( NULL != pTimer )) {
   1128     //
   1129     //  Done with this timer
   1130     //
   1131     Status = gBS->CloseEvent ( pTimer );
   1132     if ( EFI_ERROR ( Status )) {
   1133       DEBUG (( DEBUG_ERROR,
   1134                 "ERROR - Failed to free the timer event, Status: %r\r\n",
   1135                 Status ));
   1136     }
   1137     else {
   1138       DEBUG (( DEBUG_INFO,
   1139                 "0x%08x: Timer Destroyed\r\n",
   1140                 pTimer ));
   1141       pTimer = NULL;
   1142     }
   1143   }
   1144 
   1145   //
   1146   //  Return the operation status
   1147   //
   1148   return Status;
   1149 }
   1150 
   1151 
   1152 /**
   1153   Receive data from the DataSource program to test a network's bandwidth.
   1154 
   1155   @param [in] Argc  The number of arguments
   1156   @param [in] Argv  The argument value array
   1157 
   1158   @retval  0        The application exited normally.
   1159   @retval  Other    An error occurred.
   1160 **/
   1161 int
   1162 main (
   1163   IN int Argc,
   1164   IN char **Argv
   1165   )
   1166 {
   1167   sa_family_t Family;
   1168   EFI_STATUS Status;
   1169 
   1170   DEBUG (( DEBUG_INFO,
   1171             "DataSink starting\r\n" ));
   1172 
   1173   //
   1174   //  Determine the family to use
   1175   //
   1176   Family = ( 1 < Argc ) ? AF_INET6 : AF_INET;
   1177 
   1178   //
   1179   //  Use for/break instead of goto
   1180   //
   1181   for ( ; ; ) {
   1182     //
   1183     //  Create the timer
   1184     //
   1185     bTick = TRUE;
   1186     Status = TimerCreate ( );
   1187     if ( EFI_ERROR ( Status )) {
   1188       break;
   1189     }
   1190 
   1191     //
   1192     //  Start a timer to perform network polling and display updates
   1193     //
   1194     Status = TimerStart ( 1 * 1000 );
   1195     if ( EFI_ERROR ( Status )) {
   1196       break;
   1197     }
   1198 
   1199     //
   1200     //  Loop forever waiting for abuse
   1201     //
   1202     do {
   1203       ListenSocket = -1;
   1204       do {
   1205         //
   1206         //  Complete any client operations
   1207         //
   1208         Status = SocketPoll ( );
   1209         if ( EFI_ERROR ( Status )) {
   1210           //
   1211           //  Control-C
   1212           //
   1213           break;
   1214         }
   1215 
   1216         //
   1217         //  Wait for a while
   1218         //
   1219       } while ( !bTick );
   1220       if ( EFI_ERROR ( Status )) {
   1221         //
   1222         //  Control-C
   1223         //
   1224         break;
   1225       }
   1226 
   1227       //
   1228       //  Wait for the network layer to initialize
   1229       //
   1230       Status = SocketNew ( Family );
   1231       if ( EFI_ERROR ( Status )) {
   1232         continue;
   1233       }
   1234 
   1235       //
   1236       //  Wait for the remote network application to start
   1237       //
   1238       Status = SocketAccept ( );
   1239       if ( EFI_NOT_STARTED == Status ) {
   1240         Status = SocketClose ( );
   1241         continue;
   1242       }
   1243       else if ( EFI_SUCCESS != Status ) {
   1244         //
   1245         //  Control-C
   1246         //
   1247         break;
   1248       }
   1249 
   1250       //
   1251       //  Receive data until the connection breaks
   1252       //
   1253       do {
   1254         Status = SocketPoll ( );
   1255       } while ( !EFI_ERROR ( Status ));
   1256 
   1257       //
   1258       //  Done with the socket
   1259       //
   1260       Status = SocketClose ( );
   1261     } while ( !EFI_ERROR ( Status ));
   1262 
   1263     //
   1264     //  Close the socket if necessary
   1265     //
   1266     SocketClose ( );
   1267 
   1268     //
   1269     //  All done
   1270     //
   1271     break;
   1272   }
   1273 
   1274   //
   1275   //  Stop the timer if necessary
   1276   //
   1277   TimerStop ( );
   1278   TimerDestroy ( );
   1279 
   1280   //
   1281   //  Return the operation status
   1282   //
   1283   DEBUG (( DEBUG_INFO,
   1284             "DataSink exiting, Status: %r\r\n",
   1285             Status ));
   1286   return Status;
   1287 }
   1288