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