• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
ControlCCheck()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
SocketAccept()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
SocketClose()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
SocketNew(sa_family_t Family)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
SocketPoll()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
TimerCallback(IN EFI_EVENT Event,IN VOID * pContext)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
TimerCreate()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
TimerStop()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
TimerStart(UINTN Milliseconds)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
TimerDestroy()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
main(IN int Argc,IN char ** Argv)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