]> git.proxmox.com Git - mirror_edk2.git/blob - AppPkg/Applications/Sockets/DataSink/DataSink.c
dcf4b59f303436c2d7b649526f0307d537a38877
[mirror_edk2.git] / AppPkg / Applications / Sockets / DataSink / DataSink.c
1 /** @file
2 Data source for network testing.
3
4 Copyright (c) 2011, 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 htons ( 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 htons ( 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 htons ( 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 htons ( 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 htons ( 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 htons ( 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 htons ( 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 htons ( 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 htons ( 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 htons ( 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 htons ( 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 htons ( 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 htons ( 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 htons ( 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 htons ( 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 htons ( 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 htons ( 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 htons ( 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 htons ( 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 htons ( 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 }