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