2 Data source for network testing.
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
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.
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>
24 #include <netinet/in.h>
26 #include <Protocol/ServiceBinding.h>
27 #include <Protocol/Tcp4.h>
29 #include <sys/EfiSysCall.h>
31 #include <sys/socket.h>
34 #define RANGE_SWITCH 2048 ///< Switch display ranges
35 #define DATA_RATE_UPDATE_SHIFT 2 ///< 2n seconds between updates
36 #define AVERAGE_SHIFT_COUNT ( 6 - DATA_RATE_UPDATE_SHIFT ) ///< 2n samples in average
38 #define TPL_DATASOURCE TPL_CALLBACK ///< Synchronization TPL
40 #define PACKET_SIZE 1448 ///< Size of data packets
41 #define DATA_BUFFER_SIZE (( 65536 / PACKET_SIZE ) * PACKET_SIZE ) ///< Buffer size in bytes
52 BOOLEAN bTcp4
; ///< TRUE if TCP4 is being used
53 BOOLEAN bTcp4Connected
; ///< TRUE if connected to remote system
54 BOOLEAN bTcp4Connecting
; ///< TRUE while connection in progress
55 UINTN Tcp4Index
; ///< Index into handle array
56 EFI_HANDLE Tcp4Controller
; ///< Network controller handle
57 EFI_HANDLE Tcp4Handle
; ///< TCP4 port handle
58 EFI_TCP4_PROTOCOL
* pTcp4Protocol
; ///< TCP4 protocol pointer
59 EFI_SERVICE_BINDING_PROTOCOL
* pTcp4Service
; ///< TCP4 Service binding
60 EFI_TCP4_CONFIG_DATA Tcp4ConfigData
;///< TCP4 configuration data
61 EFI_TCP4_OPTION Tcp4Option
; ///< TCP4 port options
62 EFI_TCP4_CLOSE_TOKEN Tcp4CloseToken
;///< Close control
63 EFI_TCP4_CONNECTION_TOKEN Tcp4ConnectToken
; ///< Connection control
64 EFI_TCP4_LISTEN_TOKEN Tcp4ListenToken
; ///< Listen control
65 EFI_TCP4_IO_TOKEN Tcp4TxToken
; ///< Normal data token
70 volatile BOOLEAN bTick
;
71 BOOLEAN bTimerRunning
;
75 // Remote IP Address Data
77 struct sockaddr_in RemoteHostAddress
;
83 UINT64 TotalBytesSent
;
87 UINT8 Buffer
[ DATA_BUFFER_SIZE
];
91 // Forward routine declarations
93 EFI_STATUS
TimerStart ( UINTN Milliseconds
);
97 Check for control C entered at console
99 @retval EFI_SUCCESS Control C not entered
100 @retval EFI_ABORTED Control C entered
109 // Assume no user intervention
111 Status
= EFI_SUCCESS
;
114 // Display user stop request
116 if ( EFI_ERROR ( Status
)) {
118 "User stop request!\r\n" ));
122 // Return the check status
131 @param [in] pDigit The address of the next digit
132 @param [out] pValue The address to receive the value
134 @return Returns the address of the separator
149 while (( '0' <= *pDigit
) && ( '9' >= *pDigit
))
152 // Make room for the new least significant digit
157 // Convert the digit from ASCII to binary
159 Value
+= *pDigit
- '0';
162 // Set the next digit
173 // Return the next separator
182 @retval EFI_SUCCESS The IP address is valid
183 @retval Other Failure to convert the IP address
200 Status
= EFI_INVALID_PARAMETER
;
203 // Convert the IP address from a string to a numeric value
205 pSeparator
= GetDigit ( pRemoteHost
, &Value1
);
206 if (( 255 >= Value1
) && ( '.' == *pSeparator
)) {
207 pSeparator
= GetDigit ( ++pSeparator
, &Value2
);
208 if (( 255 >= Value2
) && ( '.' == *pSeparator
)) {
209 pSeparator
= GetDigit ( ++pSeparator
, &Value3
);
210 if (( 255 >= Value3
) && ( '.' == *pSeparator
)) {
211 pSeparator
= GetDigit ( ++pSeparator
, &Value4
);
212 if (( 255 >= Value4
) && ( 0 == *pSeparator
)) {
213 RemoteAddress
= Value1
217 RemoteHostAddress
.sin_addr
.s_addr
= (UINT32
) RemoteAddress
;
218 Status
= EFI_SUCCESS
;
220 "%d.%d.%d.%d: Remote host IP address\r\n",
229 if ( EFI_ERROR ( Status
)) {
230 Print ( L
"Invalid digit detected: %d\r\n", *pSeparator
);
234 // Return the operation status
243 @retval EFI_SUCCESS The application is running normally
244 @retval Other The user stopped the application
254 // Determine if the socket is open
256 Status
= EFI_DEVICE_ERROR
;
257 if ( -1 != Socket
) {
259 // Attempt to close the socket
261 CloseStatus
= close ( Socket
);
262 if ( 0 == CloseStatus
) {
264 "0x%08x: Socket closed\r\n",
267 Status
= EFI_SUCCESS
;
270 DEBUG (( DEBUG_ERROR
,
271 "ERROR: Failed to close socket, errno: %d\r\n",
277 // Return the operation status
286 @retval EFI_SUCCESS The application is running normally
287 @retval Other The user stopped the application
294 UINT32 RemoteAddress
;
298 // Display the connecting message
300 RemoteAddress
= RemoteHostAddress
.sin_addr
.s_addr
;
301 Print ( L
"Connecting to remote system %d.%d.%d.%d:%d\r\n",
302 RemoteAddress
& 0xff,
303 ( RemoteAddress
>> 8 ) & 0xff,
304 ( RemoteAddress
>> 16 ) & 0xff,
305 ( RemoteAddress
>> 24 ) & 0xff,
306 htons ( RemoteHostAddress
.sin_port
));
309 // Connect to the remote system
311 Status
= EFI_SUCCESS
;
314 // Check for user stop request
317 Status
= ControlCCheck ( );
318 if ( EFI_ERROR ( Status
)) {
323 if ( EFI_ERROR ( Status
)) {
328 // Connect to the remote system
330 ConnectStatus
= connect ( Socket
,
331 (struct sockaddr
*) &RemoteHostAddress
,
332 RemoteHostAddress
.sin_len
);
333 if ( -1 != ConnectStatus
) {
334 Print ( L
"Connected to remote system %d.%d.%d.%d:%d\r\n",
335 RemoteAddress
& 0xff,
336 ( RemoteAddress
>> 8 ) & 0xff,
337 ( RemoteAddress
>> 16 ) & 0xff,
338 ( RemoteAddress
>> 24 ) & 0xff,
339 htons ( RemoteHostAddress
.sin_port
));
343 // Close the socket and try again
345 if ( EAGAIN
!= errno
) {
346 Status
= EFI_NOT_STARTED
;
350 } while ( -1 == ConnectStatus
);
353 // Return the operation status
362 @retval EFI_SUCCESS The application is running normally
363 @retval Other The user stopped the application
372 // Loop creating the socket
375 "Creating the socket\r\n" ));
378 // Check for user stop request
380 Status
= ControlCCheck ( );
381 if ( EFI_ERROR ( Status
)) {
386 // Attempt to create the socket
388 Socket
= socket ( AF_INET
,
391 if ( -1 != Socket
) {
393 "0x%08x: Socket created\r\n",
397 } while ( -1 == Socket
);
400 // Return the operation status
407 Send data over the socket
409 @retval EFI_SUCCESS The application is running normally
410 @retval Other The user stopped the application
423 TimerStart ( 1000 << DATA_RATE_UPDATE_SHIFT
);
426 // Loop until the connection breaks or the user stops
430 // Check for user stop request
432 Status
= ControlCCheck ( );
433 if ( EFI_ERROR ( Status
)) {
440 BytesSent
= write ( Socket
, &Buffer
[0], sizeof ( Buffer
));
441 if ( -1 == BytesSent
) {
443 "ERROR: send failed, errno: %d\r\n",
449 Status
= EFI_SUCCESS
;
454 Status
= EFI_NOT_STARTED
;
459 // Synchronize with the TimerCallback routine
461 TplPrevious
= gBS
->RaiseTPL ( TPL_DATASOURCE
);
464 // Account for the data sent
466 TotalBytesSent
+= BytesSent
;
469 // Release the TimerCallback routine synchronization
471 gBS
->RestoreTPL ( TplPrevious
);
472 } while ( !EFI_ERROR ( Status
));
475 // Return the operation status
482 Open the network connection and send the data.
484 @retval EFI_SUCCESS Continue looping
485 @retval other Stopped by user's Control-C input
495 // Use do/while and break instead of goto
500 // Wait for the network layer to initialize
502 Status
= SocketNew ( );
503 if ( EFI_ERROR ( Status
)) {
508 // Wait for the remote network application to start
510 Status
= SocketConnect ( );
511 if ( EFI_NOT_STARTED
== Status
) {
512 Status
= SocketClose ( );
515 else if ( EFI_SUCCESS
!= Status
) {
523 // Send data until the connection breaks
525 Status
= SocketSend ( );
526 if ( EFI_ERROR ( Status
)) {
532 // Return the operation status
539 Close the TCP connection
541 @retval EFI_SUCCESS The application is running normally
542 @retval Other The user stopped the application
555 if ( bTcp4Connected
) {
556 Tcp4CloseToken
.AbortOnClose
= TRUE
;
557 Status
= pTcp4Protocol
->Close ( pTcp4Protocol
,
559 if ( EFI_ERROR ( Status
)) {
560 DEBUG (( DEBUG_ERROR
,
561 "ERROR - Failed to start the TCP port close, Status: %r\r\n",
565 Status
= gBS
->WaitForEvent ( 1,
566 &Tcp4CloseToken
.CompletionToken
.Event
,
568 if ( EFI_ERROR ( Status
)) {
569 DEBUG (( DEBUG_ERROR
,
570 "ERROR - Failed to wait for close event, Status: %r\r\n",
574 Status
= Tcp4CloseToken
.CompletionToken
.Status
;
575 if ( EFI_ERROR ( Status
)) {
576 DEBUG (( DEBUG_ERROR
,
577 "ERROR - Failed to close the TCP port, Status: %r\r\n",
582 "0x%08x: TCP port closed\r\n",
584 bTcp4Connected
= FALSE
;
587 // Display the port closed message
589 pIpAddress
= (UINT8
*)&RemoteHostAddress
.sin_addr
.s_addr
;
590 Print ( L
"Closed connection to %d.%d.%d.%d:%d\r\n",
595 htons ( RemoteHostAddress
.sin_port
));
602 // Release the events
604 if ( NULL
!= Tcp4TxToken
.CompletionToken
.Event
) {
605 Status
= gBS
->CloseEvent ( Tcp4TxToken
.CompletionToken
.Event
);
606 if ( !EFI_ERROR ( Status
)) {
608 "0x%08x: TX event closed\r\n",
609 Tcp4TxToken
.CompletionToken
.Event
));
610 Tcp4TxToken
.CompletionToken
.Event
= NULL
;
613 DEBUG (( DEBUG_ERROR
,
614 "ERROR - Failed to close the Tcp4TxToken event, Status: %r\r\n",
619 if ( NULL
!= Tcp4ListenToken
.CompletionToken
.Event
) {
620 Status
= gBS
->CloseEvent ( Tcp4ListenToken
.CompletionToken
.Event
);
621 if ( !EFI_ERROR ( Status
)) {
623 "0x%08x: Listen event closed\r\n",
624 Tcp4ListenToken
.CompletionToken
.Event
));
625 Tcp4ListenToken
.CompletionToken
.Event
= NULL
;
628 DEBUG (( DEBUG_ERROR
,
629 "ERROR - Failed to close the Tcp4ListenToken event, Status: %r\r\n",
634 if ( NULL
!= Tcp4ConnectToken
.CompletionToken
.Event
) {
635 Status
= gBS
->CloseEvent ( Tcp4ConnectToken
.CompletionToken
.Event
);
636 if ( !EFI_ERROR ( Status
)) {
638 "0x%08x: Connect event closed\r\n",
639 Tcp4ConnectToken
.CompletionToken
.Event
));
640 Tcp4ConnectToken
.CompletionToken
.Event
= NULL
;
643 DEBUG (( DEBUG_ERROR
,
644 "ERROR - Failed to close the Tcp4ConnectToken event, Status: %r\r\n",
649 if ( NULL
!= Tcp4CloseToken
.CompletionToken
.Event
) {
650 Status
= gBS
->CloseEvent ( Tcp4CloseToken
.CompletionToken
.Event
);
651 if ( !EFI_ERROR ( Status
)) {
653 "0x%08x: Close event closed\r\n",
654 Tcp4CloseToken
.CompletionToken
.Event
));
655 Tcp4CloseToken
.CompletionToken
.Event
= NULL
;
658 DEBUG (( DEBUG_ERROR
,
659 "ERROR - Failed to close the Tcp4CloseToken event, Status: %r\r\n",
665 // Close the TCP protocol
667 if ( NULL
!= pTcp4Protocol
) {
668 Status
= gBS
->CloseProtocol ( Tcp4Handle
,
669 &gEfiTcp4ProtocolGuid
,
672 if ( EFI_ERROR ( Status
)) {
673 DEBUG (( DEBUG_ERROR
,
674 "ERROR - Failed to close the TCP protocol, Status: %r\r\n",
679 "0x%08x: TCP4 protocol closed\r\n",
681 pTcp4Protocol
= NULL
;
686 // Done with the TCP service
688 if ( NULL
!= Tcp4Handle
) {
689 Status
= pTcp4Service
->DestroyChild ( pTcp4Service
,
691 if ( EFI_ERROR ( Status
)) {
692 DEBUG (( DEBUG_ERROR
,
693 "ERROR - Failed to release TCP service handle, Status: %r\r\n",
698 "Ox%08x: TCP service closed\r\n",
705 // Close the service protocol
707 if ( NULL
!= pTcp4Service
) {
708 Status
= gBS
->CloseProtocol ( Tcp4Controller
,
709 &gEfiTcp4ServiceBindingProtocolGuid
,
712 if ( !EFI_ERROR ( Status
)) {
714 "0x%08x: Controller closed gEfiTcp4ServiceBindingProtocolGuid protocol\r\n",
719 DEBUG (( DEBUG_ERROR
,
720 "ERROR - Failed to close the gEfiTcp4ServiceBindingProtocolGuid protocol, Status: %r\r\n",
724 Tcp4Controller
= NULL
;
725 bTcp4Connecting
= TRUE
;
728 // Mark the connection as closed
730 Status
= EFI_SUCCESS
;
733 // Return the operation status
742 @retval EFI_SUCCESS Protocol found
743 @retval other Protocl not found
750 EFI_HANDLE
* pHandles
;
755 // Use do/while and break instead of goto
759 // Attempt to locate the next TCP adapter in the system
761 Status
= gBS
->LocateHandleBuffer ( ByProtocol
,
762 &gEfiTcp4ServiceBindingProtocolGuid
,
766 if ( EFI_ERROR ( Status
)) {
768 "WARNING - No network controllers or TCP4 available, Status: %r\r\n",
774 // Wrap the index if necessary
776 if ( HandleCount
<= Tcp4Index
) {
780 // Wait for the next timer tick
788 // Display the connecting message
790 if ( bTcp4Connecting
) {
791 pIpAddress
= (UINT8
*)&RemoteHostAddress
.sin_addr
.s_addr
;
792 Print ( L
"Connecting to %d.%d.%d.%d:%d\r\n",
797 htons ( RemoteHostAddress
.sin_port
));
798 bTcp4Connecting
= FALSE
;
802 // Open the network controller's service protocol
804 Tcp4Controller
= pHandles
[ Tcp4Index
++ ];
805 Status
= gBS
->OpenProtocol (
807 &gEfiTcp4ServiceBindingProtocolGuid
,
808 (VOID
**) &pTcp4Service
,
811 EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL
);
812 if ( EFI_ERROR ( Status
)) {
813 DEBUG (( DEBUG_ERROR
,
814 "ERROR - Failed to open gEfiTcp4ServiceBindingProtocolGuid on controller 0x%08x\r\n",
816 Tcp4Controller
= NULL
;
820 "0x%08x: Controller opened gEfiTcp4ServiceBindingProtocolGuid protocol\r\n",
824 // Connect to the TCP service
826 Status
= pTcp4Service
->CreateChild ( pTcp4Service
,
828 if ( EFI_ERROR ( Status
)) {
829 DEBUG (( DEBUG_ERROR
,
830 "ERROR - Failed to open TCP service, Status: %r\r\n",
836 "Ox%08x: TCP service opened\r\n",
840 // Locate the TCP protcol
842 Status
= gBS
->OpenProtocol ( Tcp4Handle
,
843 &gEfiTcp4ProtocolGuid
,
844 (VOID
**)&pTcp4Protocol
,
847 EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL
);
848 if ( EFI_ERROR ( Status
)) {
849 DEBUG (( DEBUG_ERROR
,
850 "ERROR - Failed to open the TCP protocol, Status: %r\r\n",
852 pTcp4Protocol
= NULL
;
856 "0x%08x: TCP4 protocol opened\r\n",
861 // Release the handle buffer
863 gBS
->FreePool ( pHandles
);
866 // Return the operation status
873 Send data over the TCP4 connection
875 @retval EFI_SUCCESS The application is running normally
876 @retval Other The user stopped the application
883 EFI_TCP4_TRANSMIT_DATA Packet
;
890 TimerStart ( 1000 << DATA_RATE_UPDATE_SHIFT
);
893 // Initialize the packet
895 Packet
.DataLength
= sizeof ( Buffer
);
896 Packet
.FragmentCount
= 1;
898 Packet
.Urgent
= FALSE
;
899 Packet
.FragmentTable
[0].FragmentBuffer
= &Buffer
[0];
900 Packet
.FragmentTable
[0].FragmentLength
= sizeof ( Buffer
);
901 Tcp4TxToken
.Packet
.TxData
= &Packet
;
904 // Loop until the connection breaks or the user stops
908 // Check for user stop request
910 Status
= ControlCCheck ( );
911 if ( EFI_ERROR ( Status
)) {
918 Status
= pTcp4Protocol
->Transmit ( pTcp4Protocol
,
920 if ( EFI_ERROR ( Status
)) {
921 DEBUG (( DEBUG_ERROR
,
922 "ERROR - Failed to start the transmit, Status: %r\r\n",
928 Status
= EFI_SUCCESS
;
933 // Wait for the transmit to complete
935 Status
= gBS
->WaitForEvent ( 1,
936 &Tcp4TxToken
.CompletionToken
.Event
,
938 if ( EFI_ERROR ( Status
)) {
939 DEBUG (( DEBUG_ERROR
,
940 "ERROR - Failed to wait for transmit completion, Status: %r\r\n",
946 Status
= EFI_SUCCESS
;
951 // Get the transmit status
953 Status
= Tcp4TxToken
.CompletionToken
.Status
;
954 if ( EFI_ERROR ( Status
)) {
956 "WARNING - Failed the transmission, Status: %r\r\n",
962 Status
= EFI_SUCCESS
;
967 Status
= EFI_NOT_STARTED
;
972 // Synchronize with the TimerCallback routine
974 TplPrevious
= gBS
->RaiseTPL ( TPL_DATASOURCE
);
977 // Account for the data sent
979 TotalBytesSent
+= Packet
.DataLength
;
982 // Release the TimerCallback routine synchronization
984 gBS
->RestoreTPL ( TplPrevious
);
985 } while ( !EFI_ERROR ( Status
));
988 // Return the operation status
995 Open the network connection and send the data.
997 @retval EFI_SUCCESS Continue looping
998 @retval other Stopped by user's Control-C input
1010 // Use do/while and break instead of goto
1014 // Locate the TCP protocol
1016 Status
= Tcp4Locate ( );
1017 if ( EFI_ERROR ( Status
)) {
1022 // Create the necessary events
1024 Status
= gBS
->CreateEvent ( 0,
1028 &Tcp4CloseToken
.CompletionToken
.Event
);
1029 if ( EFI_ERROR ( Status
)) {
1030 DEBUG (( DEBUG_ERROR
,
1031 "ERROR - Failed to create the close event, Status: %r\r\n",
1033 Tcp4CloseToken
.CompletionToken
.Event
= NULL
;
1036 DEBUG (( DEBUG_INFO
,
1037 "0x%08x: Close event open\r\n",
1038 Tcp4CloseToken
.CompletionToken
.Event
));
1040 Status
= gBS
->CreateEvent ( 0,
1044 &Tcp4ConnectToken
.CompletionToken
.Event
);
1045 if ( EFI_ERROR ( Status
)) {
1046 DEBUG (( DEBUG_ERROR
,
1047 "ERROR - Failed to create the connect event, Status: %r\r\n",
1049 Tcp4ConnectToken
.CompletionToken
.Event
= NULL
;
1052 DEBUG (( DEBUG_INFO
,
1053 "0x%08x: Connect event open\r\n",
1054 Tcp4ConnectToken
.CompletionToken
.Event
));
1056 Status
= gBS
->CreateEvent ( 0,
1060 &Tcp4ListenToken
.CompletionToken
.Event
);
1061 if ( EFI_ERROR ( Status
)) {
1062 DEBUG (( DEBUG_ERROR
,
1063 "ERROR - Failed to create the listen event, Status: %r\r\n",
1065 Tcp4ListenToken
.CompletionToken
.Event
= NULL
;
1068 DEBUG (( DEBUG_INFO
,
1069 "0x%08x: Listen event open\r\n",
1070 Tcp4ListenToken
.CompletionToken
.Event
));
1072 Status
= gBS
->CreateEvent ( 0,
1076 &Tcp4TxToken
.CompletionToken
.Event
);
1077 if ( EFI_ERROR ( Status
)) {
1078 DEBUG (( DEBUG_ERROR
,
1079 "ERROR - Failed to create the TX event, Status: %r\r\n",
1081 Tcp4TxToken
.CompletionToken
.Event
= NULL
;
1084 DEBUG (( DEBUG_INFO
,
1085 "0x%08x: TX event open\r\n",
1086 Tcp4TxToken
.CompletionToken
.Event
));
1089 // Configure the local TCP port
1091 Tcp4ConfigData
.TimeToLive
= 255;
1092 Tcp4ConfigData
.TypeOfService
= 0;
1093 Tcp4ConfigData
.ControlOption
= NULL
;
1094 Tcp4ConfigData
.AccessPoint
.ActiveFlag
= TRUE
;
1095 Tcp4ConfigData
.AccessPoint
.StationAddress
.Addr
[0] = 0;
1096 Tcp4ConfigData
.AccessPoint
.StationAddress
.Addr
[1] = 0;
1097 Tcp4ConfigData
.AccessPoint
.StationAddress
.Addr
[2] = 0;
1098 Tcp4ConfigData
.AccessPoint
.StationAddress
.Addr
[3] = 0;
1099 Tcp4ConfigData
.AccessPoint
.StationPort
= 0;
1100 Tcp4ConfigData
.AccessPoint
.RemoteAddress
.Addr
[0] = (UINT8
) RemoteHostAddress
.sin_addr
.s_addr
;
1101 Tcp4ConfigData
.AccessPoint
.RemoteAddress
.Addr
[1] = (UINT8
)( RemoteHostAddress
.sin_addr
.s_addr
>> 8 );
1102 Tcp4ConfigData
.AccessPoint
.RemoteAddress
.Addr
[2] = (UINT8
)( RemoteHostAddress
.sin_addr
.s_addr
>> 16 );
1103 Tcp4ConfigData
.AccessPoint
.RemoteAddress
.Addr
[3] = (UINT8
)( RemoteHostAddress
.sin_addr
.s_addr
>> 24 );
1104 Tcp4ConfigData
.AccessPoint
.RemotePort
= RemoteHostAddress
.sin_port
;
1105 Tcp4ConfigData
.AccessPoint
.UseDefaultAddress
= TRUE
;
1106 Tcp4ConfigData
.AccessPoint
.SubnetMask
.Addr
[0] = 0;
1107 Tcp4ConfigData
.AccessPoint
.SubnetMask
.Addr
[1] = 0;
1108 Tcp4ConfigData
.AccessPoint
.SubnetMask
.Addr
[2] = 0;
1109 Tcp4ConfigData
.AccessPoint
.SubnetMask
.Addr
[3] = 0;
1110 Status
= pTcp4Protocol
->Configure ( pTcp4Protocol
,
1112 if ( EFI_ERROR ( Status
)) {
1113 DEBUG (( DEBUG_ERROR
,
1114 "ERROR - Failed to configure TCP port, Status: %r\r\n",
1118 DEBUG (( DEBUG_INFO
,
1119 "0x%08x: TCP4 port configured\r\n",
1123 // Connect to the remote TCP port
1125 Status
= pTcp4Protocol
->Connect ( pTcp4Protocol
,
1126 &Tcp4ConnectToken
);
1127 if ( EFI_ERROR ( Status
)) {
1128 DEBUG (( DEBUG_ERROR
,
1129 "ERROR - Failed to start the connection to the remote system, Status: %r\r\n",
1133 Status
= gBS
->WaitForEvent ( 1,
1134 &Tcp4ConnectToken
.CompletionToken
.Event
,
1136 if ( EFI_ERROR ( Status
)) {
1137 DEBUG (( DEBUG_ERROR
,
1138 "ERROR - Failed to wait for the connection, Status: %r\r\n",
1142 Status
= Tcp4ConnectToken
.CompletionToken
.Status
;
1143 if ( EFI_ERROR ( Status
)) {
1144 DEBUG (( DEBUG_WARN
,
1145 "WARNING - Failed to connect to the remote system, Status: %r\r\n",
1149 DEBUG (( DEBUG_INFO
,
1150 "0x%08x: TCP4 port connected\r\n",
1152 bTcp4Connected
= TRUE
;
1155 // Display the connection
1157 pIpAddress
= (UINT8
*)&RemoteHostAddress
.sin_addr
.s_addr
;
1158 Print ( L
"Connected to %d.%d.%d.%d:%d\r\n",
1163 htons ( RemoteHostAddress
.sin_port
));
1166 if ( EFI_ERROR ( Status
)) {
1170 Status
= EFI_SUCCESS
;
1174 // Semd data until the connection breaks
1176 Status
= Tcp4Send ( );
1180 // Return the operation status
1187 Handle the timer callback
1189 @param [in] Event Event that caused this callback
1190 @param [in] pContext Context for this routine
1204 // Notify the other code of the timer tick
1209 // Update the average bytes per second
1211 BytesSent
= TotalBytesSent
;
1212 if ( 0 != BytesSent
) {
1213 DeltaBytes
= AverageBytes
>> AVERAGE_SHIFT_COUNT
;
1214 AverageBytes
-= DeltaBytes
;
1215 DeltaBytes
= BytesSent
- PreviousBytes
;
1216 PreviousBytes
= BytesSent
;
1217 AverageBytes
+= DeltaBytes
;
1220 // Separate the samples
1222 if (( 2 << AVERAGE_SHIFT_COUNT
) == Samples
) {
1223 Print ( L
"---------- Stable average ----------\r\n" );
1228 // Display the data rate
1230 Delta
= (UINT32
)( DeltaBytes
>> DATA_RATE_UPDATE_SHIFT
);
1231 Average
= AverageBytes
>> ( AVERAGE_SHIFT_COUNT
+ DATA_RATE_UPDATE_SHIFT
);
1232 if ( Average
< RANGE_SWITCH
) {
1233 Print ( L
"%d Bytes/sec, Ave: %d Bytes/Sec\r\n",
1239 if ( Average
< RANGE_SWITCH
) {
1240 Print ( L
"%d Bytes/sec, Ave: %d KiBytes/Sec\r\n",
1246 if ( Average
< RANGE_SWITCH
) {
1247 Print ( L
"%d Bytes/sec, Ave: %d MiBytes/Sec\r\n",
1253 if ( Average
< RANGE_SWITCH
) {
1254 Print ( L
"%d Bytes/sec, Ave: %d GiBytes/Sec\r\n",
1260 if ( Average
< RANGE_SWITCH
) {
1261 Print ( L
"%d Bytes/sec, Ave: %d TiBytes/Sec\r\n",
1267 Print ( L
"%d Bytes/sec, Ave: %d PiBytes/Sec\r\n",
1282 @retval EFI_SUCCESS The timer was successfully created
1283 @retval Other Timer initialization failed
1294 Status
= gBS
->CreateEvent ( EVT_TIMER
| EVT_NOTIFY_SIGNAL
,
1299 if ( EFI_ERROR ( Status
)) {
1300 DEBUG (( DEBUG_ERROR
,
1301 "ERROR - Failed to allocate the timer event, Status: %r\r\n",
1305 DEBUG (( DEBUG_INFO
,
1306 "0x%08x: Timer created\r\n",
1311 // Return the operation status
1320 @retval EFI_SUCCESS The timer was stopped successfully
1321 @retval Other The timer failed to stop
1332 Status
= EFI_SUCCESS
;
1335 // Determine if the timer is running
1337 if ( bTimerRunning
) {
1341 Status
= gBS
->SetTimer ( pTimer
,
1344 if ( EFI_ERROR ( Status
)) {
1345 DEBUG (( DEBUG_ERROR
,
1346 "ERROR - Failed to stop the timer, Status: %r\r\n",
1351 // Timer timer is now stopped
1353 bTimerRunning
= FALSE
;
1354 DEBUG (( DEBUG_INFO
,
1355 "0x%08x: Timer stopped\r\n",
1361 // Return the operation status
1370 @param [in] Milliseconds The number of milliseconds between timer callbacks
1372 @retval EFI_SUCCESS The timer was successfully created
1373 @retval Other Timer initialization failed
1384 // Stop the timer if necessary
1386 Status
= EFI_SUCCESS
;
1387 if ( bTimerRunning
) {
1388 Status
= TimerStop ( );
1390 if ( !EFI_ERROR ( Status
)) {
1392 // Compute the new delay
1394 TimeDelay
= Milliseconds
;
1395 TimeDelay
*= 1000 * 10;
1400 Status
= gBS
->SetTimer ( pTimer
,
1403 if ( EFI_ERROR ( Status
)) {
1404 DEBUG (( DEBUG_ERROR
,
1405 "ERROR - Failed to start the timer, Status: %r\r\n",
1410 // The timer is now running
1412 bTimerRunning
= TRUE
;
1413 DEBUG (( DEBUG_INFO
,
1414 "0x%08x: Timer running\r\n",
1420 // Return the operation status
1429 @retval EFI_SUCCESS The timer was destroyed successfully
1430 @retval Other Failed to destroy the timer
1441 Status
= EFI_SUCCESS
;
1444 // Determine if the timer is running
1446 if ( bTimerRunning
) {
1450 Status
= TimerStop ( );
1452 if (( !EFI_ERROR ( Status
)) && ( NULL
!= pTimer
)) {
1454 // Done with this timer
1456 Status
= gBS
->CloseEvent ( pTimer
);
1457 if ( EFI_ERROR ( Status
)) {
1458 DEBUG (( DEBUG_ERROR
,
1459 "ERROR - Failed to free the timer event, Status: %r\r\n",
1463 DEBUG (( DEBUG_INFO
,
1464 "0x%08x: Timer Destroyed\r\n",
1471 // Return the operation status
1478 Send data to the DataSink program to test a network's bandwidth.
1480 @param [in] Argc The number of arguments
1481 @param [in] Argv The argument value array
1483 @retval 0 The application exited normally.
1484 @retval Other An error occurred.
1492 EFI_STATUS (* pClose
) ();
1493 EFI_STATUS (* pOpen
) ();
1496 DEBUG (( DEBUG_INFO
,
1497 "DataSource starting\r\n" ));
1500 // Validate the command line
1503 Print ( L
"%s <remote IP address>\r\n", Argv
[0] );
1510 // Determine the support routines
1515 bTcp4Connecting
= TRUE
;
1519 pClose
= SocketClose
;
1523 // Use for/break instead of goto
1528 // No bytes sent so far
1536 // Get the port number
1538 ZeroMem ( &RemoteHostAddress
, sizeof ( RemoteHostAddress
));
1539 RemoteHostAddress
.sin_len
= sizeof ( RemoteHostAddress
);
1540 RemoteHostAddress
.sin_family
= AF_INET
;
1541 RemoteHostAddress
.sin_port
= htons ( PcdGet16 ( DataSource_Port
));
1543 Print ( L
"Argc: %d\r\n", Argc
);
1544 Print ( L
"Argv[0]: %a\r\n", Argv
[0]);
1545 Print ( L
"Argv[1]: %a\r\n", Argv
[1]);
1548 // Get the IP address
1550 pRemoteHost
= Argv
[1];
1551 Status
= IpAddress ( );
1552 if ( EFI_ERROR ( Status
)) {
1560 Status
= TimerCreate ( );
1561 if ( EFI_ERROR ( Status
)) {
1566 // Loop forever abusing the specified system
1570 // Start a timer to perform connection polling and display updates
1572 Status
= TimerStart ( 2 * 1000 );
1573 if ( EFI_ERROR ( Status
)) {
1578 // Open the network connection and send the data
1581 if ( EFI_ERROR ( Status
)) {
1586 // Done with the network connection
1588 Status
= pClose ( );
1589 } while ( !EFI_ERROR ( Status
));
1592 // Close the network connection if necessary
1603 // Stop the timer if necessary
1609 // Return the operation status
1611 DEBUG (( DEBUG_INFO
,
1612 "DataSource exiting, Status: %r\r\n",