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