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
)) {
151 // Make room for the new least significant digit
156 // Convert the digit from ASCII to binary
158 Value
+= *pDigit
- '0';
161 // Set the next digit
172 // Return the next separator
181 @retval EFI_SUCCESS The IP address is valid
182 @retval Other Failure to convert the IP address
199 Status
= EFI_INVALID_PARAMETER
;
202 // Convert the IP address from a string to a numeric value
204 pSeparator
= GetDigit ( pRemoteHost
, &Value1
);
205 if (( 255 >= Value1
) && ( '.' == *pSeparator
)) {
206 pSeparator
= GetDigit ( ++pSeparator
, &Value2
);
207 if (( 255 >= Value2
) && ( '.' == *pSeparator
)) {
208 pSeparator
= GetDigit ( ++pSeparator
, &Value3
);
209 if (( 255 >= Value3
) && ( '.' == *pSeparator
)) {
210 pSeparator
= GetDigit ( ++pSeparator
, &Value4
);
211 if (( 255 >= Value4
) && ( 0 == *pSeparator
)) {
212 RemoteAddress
= Value1
216 RemoteHostAddress
.sin_addr
.s_addr
= (UINT32
) RemoteAddress
;
217 Status
= EFI_SUCCESS
;
219 "%d.%d.%d.%d: Remote host IP address\r\n",
228 if ( EFI_ERROR ( Status
)) {
229 Print ( L
"Invalid digit detected: %d\r\n", *pSeparator
);
233 // Return the operation status
242 @retval EFI_SUCCESS The application is running normally
243 @retval Other The user stopped the application
253 // Determine if the socket is open
255 Status
= EFI_DEVICE_ERROR
;
256 if ( -1 != Socket
) {
258 // Attempt to close the socket
260 CloseStatus
= close ( Socket
);
261 if ( 0 == CloseStatus
) {
263 "0x%08x: Socket closed\r\n",
266 Status
= EFI_SUCCESS
;
269 DEBUG (( DEBUG_ERROR
,
270 "ERROR: Failed to close socket, errno: %d\r\n",
276 // Return the operation status
285 @retval EFI_SUCCESS The application is running normally
286 @retval Other The user stopped the application
293 UINT32 RemoteAddress
;
297 // Display the connecting message
299 RemoteAddress
= RemoteHostAddress
.sin_addr
.s_addr
;
300 Print ( L
"Connecting to remote system %d.%d.%d.%d:%d\r\n",
301 RemoteAddress
& 0xff,
302 ( RemoteAddress
>> 8 ) & 0xff,
303 ( RemoteAddress
>> 16 ) & 0xff,
304 ( RemoteAddress
>> 24 ) & 0xff,
305 htons ( RemoteHostAddress
.sin_port
));
308 // Connect to the remote system
310 Status
= EFI_SUCCESS
;
313 // Check for user stop request
316 Status
= ControlCCheck ( );
317 if ( EFI_ERROR ( Status
)) {
322 if ( EFI_ERROR ( Status
)) {
327 // Connect to the remote system
329 ConnectStatus
= connect ( Socket
,
330 (struct sockaddr
*) &RemoteHostAddress
,
331 RemoteHostAddress
.sin_len
);
332 if ( -1 != ConnectStatus
) {
333 Print ( L
"Connected to remote system %d.%d.%d.%d:%d\r\n",
334 RemoteAddress
& 0xff,
335 ( RemoteAddress
>> 8 ) & 0xff,
336 ( RemoteAddress
>> 16 ) & 0xff,
337 ( RemoteAddress
>> 24 ) & 0xff,
338 htons ( RemoteHostAddress
.sin_port
));
342 // Close the socket and try again
344 if ( EAGAIN
!= errno
) {
345 Status
= EFI_NOT_STARTED
;
349 } while ( -1 == ConnectStatus
);
352 // Return the operation status
361 @retval EFI_SUCCESS The application is running normally
362 @retval Other The user stopped the application
371 // Loop creating the socket
374 "Creating the socket\r\n" ));
377 // Check for user stop request
379 Status
= ControlCCheck ( );
380 if ( EFI_ERROR ( Status
)) {
385 // Attempt to create the socket
387 Socket
= socket ( AF_INET
,
390 if ( -1 != Socket
) {
392 "0x%08x: Socket created\r\n",
396 } while ( -1 == Socket
);
399 // Return the operation status
406 Send data over the socket
408 @retval EFI_SUCCESS The application is running normally
409 @retval Other The user stopped the application
422 TimerStart ( 1000 << DATA_RATE_UPDATE_SHIFT
);
425 // Loop until the connection breaks or the user stops
429 // Check for user stop request
431 Status
= ControlCCheck ( );
432 if ( EFI_ERROR ( Status
)) {
439 BytesSent
= write ( Socket
, &Buffer
[0], sizeof ( Buffer
));
440 if ( -1 == BytesSent
) {
442 "ERROR: send failed, errno: %d\r\n",
448 Status
= EFI_SUCCESS
;
453 Status
= EFI_NOT_STARTED
;
458 // Synchronize with the TimerCallback routine
460 TplPrevious
= gBS
->RaiseTPL ( TPL_DATASOURCE
);
463 // Account for the data sent
465 TotalBytesSent
+= BytesSent
;
468 // Release the TimerCallback routine synchronization
470 gBS
->RestoreTPL ( TplPrevious
);
471 } while ( !EFI_ERROR ( Status
));
474 // Return the operation status
481 Open the network connection and send the data.
483 @retval EFI_SUCCESS Continue looping
484 @retval other Stopped by user's Control-C input
494 // Use do/while and break instead of goto
498 // Wait for the network layer to initialize
500 Status
= SocketNew ( );
501 if ( EFI_ERROR ( Status
)) {
506 // Wait for the remote network application to start
508 Status
= SocketConnect ( );
509 if ( EFI_NOT_STARTED
== Status
) {
510 Status
= SocketClose ( );
513 else if ( EFI_SUCCESS
!= Status
) {
521 // Send data until the connection breaks
523 Status
= SocketSend ( );
524 if ( EFI_ERROR ( Status
)) {
530 // Return the operation status
537 Close the TCP connection
539 @retval EFI_SUCCESS The application is running normally
540 @retval Other The user stopped the application
553 if ( bTcp4Connected
) {
554 Tcp4CloseToken
.AbortOnClose
= TRUE
;
555 Status
= pTcp4Protocol
->Close ( pTcp4Protocol
,
557 if ( EFI_ERROR ( Status
)) {
558 DEBUG (( DEBUG_ERROR
,
559 "ERROR - Failed to start the TCP port close, Status: %r\r\n",
563 Status
= gBS
->WaitForEvent ( 1,
564 &Tcp4CloseToken
.CompletionToken
.Event
,
566 if ( EFI_ERROR ( Status
)) {
567 DEBUG (( DEBUG_ERROR
,
568 "ERROR - Failed to wait for close event, Status: %r\r\n",
572 Status
= Tcp4CloseToken
.CompletionToken
.Status
;
573 if ( EFI_ERROR ( Status
)) {
574 DEBUG (( DEBUG_ERROR
,
575 "ERROR - Failed to close the TCP port, Status: %r\r\n",
580 "0x%08x: TCP port closed\r\n",
582 bTcp4Connected
= FALSE
;
585 // Display the port closed message
587 pIpAddress
= (UINT8
*)&RemoteHostAddress
.sin_addr
.s_addr
;
588 Print ( L
"Closed connection to %d.%d.%d.%d:%d\r\n",
593 htons ( RemoteHostAddress
.sin_port
));
600 // Release the events
602 if ( NULL
!= Tcp4TxToken
.CompletionToken
.Event
) {
603 Status
= gBS
->CloseEvent ( Tcp4TxToken
.CompletionToken
.Event
);
604 if ( !EFI_ERROR ( Status
)) {
606 "0x%08x: TX event closed\r\n",
607 Tcp4TxToken
.CompletionToken
.Event
));
608 Tcp4TxToken
.CompletionToken
.Event
= NULL
;
611 DEBUG (( DEBUG_ERROR
,
612 "ERROR - Failed to close the Tcp4TxToken event, Status: %r\r\n",
617 if ( NULL
!= Tcp4ListenToken
.CompletionToken
.Event
) {
618 Status
= gBS
->CloseEvent ( Tcp4ListenToken
.CompletionToken
.Event
);
619 if ( !EFI_ERROR ( Status
)) {
621 "0x%08x: Listen event closed\r\n",
622 Tcp4ListenToken
.CompletionToken
.Event
));
623 Tcp4ListenToken
.CompletionToken
.Event
= NULL
;
626 DEBUG (( DEBUG_ERROR
,
627 "ERROR - Failed to close the Tcp4ListenToken event, Status: %r\r\n",
632 if ( NULL
!= Tcp4ConnectToken
.CompletionToken
.Event
) {
633 Status
= gBS
->CloseEvent ( Tcp4ConnectToken
.CompletionToken
.Event
);
634 if ( !EFI_ERROR ( Status
)) {
636 "0x%08x: Connect event closed\r\n",
637 Tcp4ConnectToken
.CompletionToken
.Event
));
638 Tcp4ConnectToken
.CompletionToken
.Event
= NULL
;
641 DEBUG (( DEBUG_ERROR
,
642 "ERROR - Failed to close the Tcp4ConnectToken event, Status: %r\r\n",
647 if ( NULL
!= Tcp4CloseToken
.CompletionToken
.Event
) {
648 Status
= gBS
->CloseEvent ( Tcp4CloseToken
.CompletionToken
.Event
);
649 if ( !EFI_ERROR ( Status
)) {
651 "0x%08x: Close event closed\r\n",
652 Tcp4CloseToken
.CompletionToken
.Event
));
653 Tcp4CloseToken
.CompletionToken
.Event
= NULL
;
656 DEBUG (( DEBUG_ERROR
,
657 "ERROR - Failed to close the Tcp4CloseToken event, Status: %r\r\n",
663 // Close the TCP protocol
665 if ( NULL
!= pTcp4Protocol
) {
666 Status
= gBS
->CloseProtocol ( Tcp4Handle
,
667 &gEfiTcp4ProtocolGuid
,
670 if ( EFI_ERROR ( Status
)) {
671 DEBUG (( DEBUG_ERROR
,
672 "ERROR - Failed to close the TCP protocol, Status: %r\r\n",
677 "0x%08x: TCP4 protocol closed\r\n",
679 pTcp4Protocol
= NULL
;
684 // Done with the TCP service
686 if ( NULL
!= Tcp4Handle
) {
687 Status
= pTcp4Service
->DestroyChild ( pTcp4Service
,
689 if ( EFI_ERROR ( Status
)) {
690 DEBUG (( DEBUG_ERROR
,
691 "ERROR - Failed to release TCP service handle, Status: %r\r\n",
696 "Ox%08x: TCP service closed\r\n",
703 // Close the service protocol
705 if ( NULL
!= pTcp4Service
) {
706 Status
= gBS
->CloseProtocol ( Tcp4Controller
,
707 &gEfiTcp4ServiceBindingProtocolGuid
,
710 if ( !EFI_ERROR ( Status
)) {
712 "0x%08x: Controller closed gEfiTcp4ServiceBindingProtocolGuid protocol\r\n",
717 DEBUG (( DEBUG_ERROR
,
718 "ERROR - Failed to close the gEfiTcp4ServiceBindingProtocolGuid protocol, Status: %r\r\n",
722 Tcp4Controller
= NULL
;
723 bTcp4Connecting
= TRUE
;
726 // Mark the connection as closed
728 Status
= EFI_SUCCESS
;
731 // Return the operation status
740 @retval EFI_SUCCESS Protocol found
741 @retval other Protocl not found
748 EFI_HANDLE
* pHandles
;
753 // Use do/while and break instead of goto
757 // Attempt to locate the next TCP adapter in the system
759 Status
= gBS
->LocateHandleBuffer ( ByProtocol
,
760 &gEfiTcp4ServiceBindingProtocolGuid
,
764 if ( EFI_ERROR ( Status
)) {
766 "WARNING - No network controllers or TCP4 available, Status: %r\r\n",
772 // Wrap the index if necessary
774 if ( HandleCount
<= Tcp4Index
) {
778 // Wait for the next timer tick
786 // Display the connecting message
788 if ( bTcp4Connecting
) {
789 pIpAddress
= (UINT8
*)&RemoteHostAddress
.sin_addr
.s_addr
;
790 Print ( L
"Connecting to %d.%d.%d.%d:%d\r\n",
795 htons ( RemoteHostAddress
.sin_port
));
796 bTcp4Connecting
= FALSE
;
800 // Open the network controller's service protocol
802 Tcp4Controller
= pHandles
[ Tcp4Index
++ ];
803 Status
= gBS
->OpenProtocol (
805 &gEfiTcp4ServiceBindingProtocolGuid
,
806 (VOID
**) &pTcp4Service
,
809 EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL
);
810 if ( EFI_ERROR ( Status
)) {
811 DEBUG (( DEBUG_ERROR
,
812 "ERROR - Failed to open gEfiTcp4ServiceBindingProtocolGuid on controller 0x%08x\r\n",
814 Tcp4Controller
= NULL
;
818 "0x%08x: Controller opened gEfiTcp4ServiceBindingProtocolGuid protocol\r\n",
822 // Connect to the TCP service
824 Status
= pTcp4Service
->CreateChild ( pTcp4Service
,
826 if ( EFI_ERROR ( Status
)) {
827 DEBUG (( DEBUG_ERROR
,
828 "ERROR - Failed to open TCP service, Status: %r\r\n",
834 "Ox%08x: TCP service opened\r\n",
838 // Locate the TCP protcol
840 Status
= gBS
->OpenProtocol ( Tcp4Handle
,
841 &gEfiTcp4ProtocolGuid
,
842 (VOID
**)&pTcp4Protocol
,
845 EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL
);
846 if ( EFI_ERROR ( Status
)) {
847 DEBUG (( DEBUG_ERROR
,
848 "ERROR - Failed to open the TCP protocol, Status: %r\r\n",
850 pTcp4Protocol
= NULL
;
854 "0x%08x: TCP4 protocol opened\r\n",
859 // Release the handle buffer
861 gBS
->FreePool ( pHandles
);
864 // Return the operation status
871 Send data over the TCP4 connection
873 @retval EFI_SUCCESS The application is running normally
874 @retval Other The user stopped the application
881 EFI_TCP4_TRANSMIT_DATA Packet
;
888 TimerStart ( 1000 << DATA_RATE_UPDATE_SHIFT
);
891 // Initialize the packet
893 Packet
.DataLength
= sizeof ( Buffer
);
894 Packet
.FragmentCount
= 1;
896 Packet
.Urgent
= FALSE
;
897 Packet
.FragmentTable
[0].FragmentBuffer
= &Buffer
[0];
898 Packet
.FragmentTable
[0].FragmentLength
= sizeof ( Buffer
);
899 Tcp4TxToken
.Packet
.TxData
= &Packet
;
902 // Loop until the connection breaks or the user stops
906 // Check for user stop request
908 Status
= ControlCCheck ( );
909 if ( EFI_ERROR ( Status
)) {
916 Status
= pTcp4Protocol
->Transmit ( pTcp4Protocol
,
918 if ( EFI_ERROR ( Status
)) {
919 DEBUG (( DEBUG_ERROR
,
920 "ERROR - Failed to start the transmit, Status: %r\r\n",
926 Status
= EFI_SUCCESS
;
931 // Wait for the transmit to complete
933 Status
= gBS
->WaitForEvent ( 1,
934 &Tcp4TxToken
.CompletionToken
.Event
,
936 if ( EFI_ERROR ( Status
)) {
937 DEBUG (( DEBUG_ERROR
,
938 "ERROR - Failed to wait for transmit completion, Status: %r\r\n",
944 Status
= EFI_SUCCESS
;
949 // Get the transmit status
951 Status
= Tcp4TxToken
.CompletionToken
.Status
;
952 if ( EFI_ERROR ( Status
)) {
954 "WARNING - Failed the transmission, Status: %r\r\n",
960 Status
= EFI_SUCCESS
;
965 Status
= EFI_NOT_STARTED
;
970 // Synchronize with the TimerCallback routine
972 TplPrevious
= gBS
->RaiseTPL ( TPL_DATASOURCE
);
975 // Account for the data sent
977 TotalBytesSent
+= Packet
.DataLength
;
980 // Release the TimerCallback routine synchronization
982 gBS
->RestoreTPL ( TplPrevious
);
983 } while ( !EFI_ERROR ( Status
));
986 // Return the operation status
993 Open the network connection and send the data.
995 @retval EFI_SUCCESS Continue looping
996 @retval other Stopped by user's Control-C input
1008 // Use do/while and break instead of goto
1012 // Locate the TCP protocol
1014 Status
= Tcp4Locate ( );
1015 if ( EFI_ERROR ( Status
)) {
1020 // Create the necessary events
1022 Status
= gBS
->CreateEvent ( 0,
1026 &Tcp4CloseToken
.CompletionToken
.Event
);
1027 if ( EFI_ERROR ( Status
)) {
1028 DEBUG (( DEBUG_ERROR
,
1029 "ERROR - Failed to create the close event, Status: %r\r\n",
1031 Tcp4CloseToken
.CompletionToken
.Event
= NULL
;
1034 DEBUG (( DEBUG_INFO
,
1035 "0x%08x: Close event open\r\n",
1036 Tcp4CloseToken
.CompletionToken
.Event
));
1038 Status
= gBS
->CreateEvent ( 0,
1042 &Tcp4ConnectToken
.CompletionToken
.Event
);
1043 if ( EFI_ERROR ( Status
)) {
1044 DEBUG (( DEBUG_ERROR
,
1045 "ERROR - Failed to create the connect event, Status: %r\r\n",
1047 Tcp4ConnectToken
.CompletionToken
.Event
= NULL
;
1050 DEBUG (( DEBUG_INFO
,
1051 "0x%08x: Connect event open\r\n",
1052 Tcp4ConnectToken
.CompletionToken
.Event
));
1054 Status
= gBS
->CreateEvent ( 0,
1058 &Tcp4ListenToken
.CompletionToken
.Event
);
1059 if ( EFI_ERROR ( Status
)) {
1060 DEBUG (( DEBUG_ERROR
,
1061 "ERROR - Failed to create the listen event, Status: %r\r\n",
1063 Tcp4ListenToken
.CompletionToken
.Event
= NULL
;
1066 DEBUG (( DEBUG_INFO
,
1067 "0x%08x: Listen event open\r\n",
1068 Tcp4ListenToken
.CompletionToken
.Event
));
1070 Status
= gBS
->CreateEvent ( 0,
1074 &Tcp4TxToken
.CompletionToken
.Event
);
1075 if ( EFI_ERROR ( Status
)) {
1076 DEBUG (( DEBUG_ERROR
,
1077 "ERROR - Failed to create the TX event, Status: %r\r\n",
1079 Tcp4TxToken
.CompletionToken
.Event
= NULL
;
1082 DEBUG (( DEBUG_INFO
,
1083 "0x%08x: TX event open\r\n",
1084 Tcp4TxToken
.CompletionToken
.Event
));
1087 // Configure the local TCP port
1089 Tcp4ConfigData
.TimeToLive
= 255;
1090 Tcp4ConfigData
.TypeOfService
= 0;
1091 Tcp4ConfigData
.ControlOption
= NULL
;
1092 Tcp4ConfigData
.AccessPoint
.ActiveFlag
= TRUE
;
1093 Tcp4ConfigData
.AccessPoint
.StationAddress
.Addr
[0] = 0;
1094 Tcp4ConfigData
.AccessPoint
.StationAddress
.Addr
[1] = 0;
1095 Tcp4ConfigData
.AccessPoint
.StationAddress
.Addr
[2] = 0;
1096 Tcp4ConfigData
.AccessPoint
.StationAddress
.Addr
[3] = 0;
1097 Tcp4ConfigData
.AccessPoint
.StationPort
= 0;
1098 Tcp4ConfigData
.AccessPoint
.RemoteAddress
.Addr
[0] = (UINT8
) RemoteHostAddress
.sin_addr
.s_addr
;
1099 Tcp4ConfigData
.AccessPoint
.RemoteAddress
.Addr
[1] = (UINT8
)( RemoteHostAddress
.sin_addr
.s_addr
>> 8 );
1100 Tcp4ConfigData
.AccessPoint
.RemoteAddress
.Addr
[2] = (UINT8
)( RemoteHostAddress
.sin_addr
.s_addr
>> 16 );
1101 Tcp4ConfigData
.AccessPoint
.RemoteAddress
.Addr
[3] = (UINT8
)( RemoteHostAddress
.sin_addr
.s_addr
>> 24 );
1102 Tcp4ConfigData
.AccessPoint
.RemotePort
= RemoteHostAddress
.sin_port
;
1103 Tcp4ConfigData
.AccessPoint
.UseDefaultAddress
= TRUE
;
1104 Tcp4ConfigData
.AccessPoint
.SubnetMask
.Addr
[0] = 0;
1105 Tcp4ConfigData
.AccessPoint
.SubnetMask
.Addr
[1] = 0;
1106 Tcp4ConfigData
.AccessPoint
.SubnetMask
.Addr
[2] = 0;
1107 Tcp4ConfigData
.AccessPoint
.SubnetMask
.Addr
[3] = 0;
1108 Status
= pTcp4Protocol
->Configure ( pTcp4Protocol
,
1110 if ( EFI_ERROR ( Status
)) {
1111 DEBUG (( DEBUG_ERROR
,
1112 "ERROR - Failed to configure TCP port, Status: %r\r\n",
1116 DEBUG (( DEBUG_INFO
,
1117 "0x%08x: TCP4 port configured\r\n",
1121 // Connect to the remote TCP port
1123 Status
= pTcp4Protocol
->Connect ( pTcp4Protocol
,
1124 &Tcp4ConnectToken
);
1125 if ( EFI_ERROR ( Status
)) {
1126 DEBUG (( DEBUG_ERROR
,
1127 "ERROR - Failed to start the connection to the remote system, Status: %r\r\n",
1131 Status
= gBS
->WaitForEvent ( 1,
1132 &Tcp4ConnectToken
.CompletionToken
.Event
,
1134 if ( EFI_ERROR ( Status
)) {
1135 DEBUG (( DEBUG_ERROR
,
1136 "ERROR - Failed to wait for the connection, Status: %r\r\n",
1140 Status
= Tcp4ConnectToken
.CompletionToken
.Status
;
1141 if ( EFI_ERROR ( Status
)) {
1142 DEBUG (( DEBUG_WARN
,
1143 "WARNING - Failed to connect to the remote system, Status: %r\r\n",
1147 DEBUG (( DEBUG_INFO
,
1148 "0x%08x: TCP4 port connected\r\n",
1150 bTcp4Connected
= TRUE
;
1153 // Display the connection
1155 pIpAddress
= (UINT8
*)&RemoteHostAddress
.sin_addr
.s_addr
;
1156 Print ( L
"Connected to %d.%d.%d.%d:%d\r\n",
1161 htons ( RemoteHostAddress
.sin_port
));
1164 if ( EFI_ERROR ( Status
)) {
1168 Status
= EFI_SUCCESS
;
1172 // Semd data until the connection breaks
1174 Status
= Tcp4Send ( );
1178 // Return the operation status
1185 Handle the timer callback
1187 @param [in] Event Event that caused this callback
1188 @param [in] pContext Context for this routine
1202 // Notify the other code of the timer tick
1207 // Update the average bytes per second
1209 BytesSent
= TotalBytesSent
;
1210 if ( 0 != BytesSent
) {
1211 DeltaBytes
= AverageBytes
>> AVERAGE_SHIFT_COUNT
;
1212 AverageBytes
-= DeltaBytes
;
1213 DeltaBytes
= BytesSent
- PreviousBytes
;
1214 PreviousBytes
= BytesSent
;
1215 AverageBytes
+= DeltaBytes
;
1218 // Separate the samples
1220 if (( 2 << AVERAGE_SHIFT_COUNT
) == Samples
) {
1221 Print ( L
"---------- Stable average ----------\r\n" );
1226 // Display the data rate
1228 Delta
= (UINT32
)( DeltaBytes
>> DATA_RATE_UPDATE_SHIFT
);
1229 Average
= AverageBytes
>> ( AVERAGE_SHIFT_COUNT
+ DATA_RATE_UPDATE_SHIFT
);
1230 if ( Average
< RANGE_SWITCH
) {
1231 Print ( L
"%d Bytes/sec, Ave: %d Bytes/Sec\r\n",
1237 if ( Average
< RANGE_SWITCH
) {
1238 Print ( L
"%d Bytes/sec, Ave: %d KiBytes/Sec\r\n",
1244 if ( Average
< RANGE_SWITCH
) {
1245 Print ( L
"%d Bytes/sec, Ave: %d MiBytes/Sec\r\n",
1251 if ( Average
< RANGE_SWITCH
) {
1252 Print ( L
"%d Bytes/sec, Ave: %d GiBytes/Sec\r\n",
1258 if ( Average
< RANGE_SWITCH
) {
1259 Print ( L
"%d Bytes/sec, Ave: %d TiBytes/Sec\r\n",
1265 Print ( L
"%d Bytes/sec, Ave: %d PiBytes/Sec\r\n",
1280 @retval EFI_SUCCESS The timer was successfully created
1281 @retval Other Timer initialization failed
1292 Status
= gBS
->CreateEvent ( EVT_TIMER
| EVT_NOTIFY_SIGNAL
,
1297 if ( EFI_ERROR ( Status
)) {
1298 DEBUG (( DEBUG_ERROR
,
1299 "ERROR - Failed to allocate the timer event, Status: %r\r\n",
1303 DEBUG (( DEBUG_INFO
,
1304 "0x%08x: Timer created\r\n",
1309 // Return the operation status
1318 @retval EFI_SUCCESS The timer was stopped successfully
1319 @retval Other The timer failed to stop
1330 Status
= EFI_SUCCESS
;
1333 // Determine if the timer is running
1335 if ( bTimerRunning
) {
1339 Status
= gBS
->SetTimer ( pTimer
,
1342 if ( EFI_ERROR ( Status
)) {
1343 DEBUG (( DEBUG_ERROR
,
1344 "ERROR - Failed to stop the timer, Status: %r\r\n",
1349 // Timer timer is now stopped
1351 bTimerRunning
= FALSE
;
1352 DEBUG (( DEBUG_INFO
,
1353 "0x%08x: Timer stopped\r\n",
1359 // Return the operation status
1368 @param [in] Milliseconds The number of milliseconds between timer callbacks
1370 @retval EFI_SUCCESS The timer was successfully created
1371 @retval Other Timer initialization failed
1382 // Stop the timer if necessary
1384 Status
= EFI_SUCCESS
;
1385 if ( bTimerRunning
) {
1386 Status
= TimerStop ( );
1388 if ( !EFI_ERROR ( Status
)) {
1390 // Compute the new delay
1392 TimeDelay
= Milliseconds
;
1393 TimeDelay
*= 1000 * 10;
1398 Status
= gBS
->SetTimer ( pTimer
,
1401 if ( EFI_ERROR ( Status
)) {
1402 DEBUG (( DEBUG_ERROR
,
1403 "ERROR - Failed to start the timer, Status: %r\r\n",
1408 // The timer is now running
1410 bTimerRunning
= TRUE
;
1411 DEBUG (( DEBUG_INFO
,
1412 "0x%08x: Timer running\r\n",
1418 // Return the operation status
1427 @retval EFI_SUCCESS The timer was destroyed successfully
1428 @retval Other Failed to destroy the timer
1439 Status
= EFI_SUCCESS
;
1442 // Determine if the timer is running
1444 if ( bTimerRunning
) {
1448 Status
= TimerStop ( );
1450 if (( !EFI_ERROR ( Status
)) && ( NULL
!= pTimer
)) {
1452 // Done with this timer
1454 Status
= gBS
->CloseEvent ( pTimer
);
1455 if ( EFI_ERROR ( Status
)) {
1456 DEBUG (( DEBUG_ERROR
,
1457 "ERROR - Failed to free the timer event, Status: %r\r\n",
1461 DEBUG (( DEBUG_INFO
,
1462 "0x%08x: Timer Destroyed\r\n",
1469 // Return the operation status
1476 Send data to the DataSink program to test a network's bandwidth.
1478 @param [in] Argc The number of arguments
1479 @param [in] Argv The argument value array
1481 @retval 0 The application exited normally.
1482 @retval Other An error occurred.
1490 EFI_STATUS (* pClose
) ();
1491 EFI_STATUS (* pOpen
) ();
1494 DEBUG (( DEBUG_INFO
,
1495 "DataSource starting\r\n" ));
1498 // Validate the command line
1501 Print ( L
"%s <remote IP address> [Use TCP]\r\n", Argv
[0] );
1506 // Determine if TCP should be used
1508 bTcp4
= (BOOLEAN
)( 2 < Argc
);
1511 // Determine the support routines
1516 bTcp4Connecting
= TRUE
;
1520 pClose
= SocketClose
;
1524 // 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
));
1544 // Get the IP address
1546 pRemoteHost
= Argv
[1];
1547 Status
= IpAddress ( );
1548 if ( EFI_ERROR ( Status
)) {
1556 Status
= TimerCreate ( );
1557 if ( EFI_ERROR ( Status
)) {
1562 // Loop forever abusing the specified system
1566 // Start a timer to perform connection polling and display updates
1568 Status
= TimerStart ( 2 * 1000 );
1569 if ( EFI_ERROR ( Status
)) {
1574 // Open the network connection and send the data
1577 if ( EFI_ERROR ( Status
)) {
1582 // Done with the network connection
1584 Status
= pClose ( );
1585 } while ( !EFI_ERROR ( Status
));
1588 // Close the network connection if necessary
1599 // Stop the timer if necessary
1605 // Return the operation status
1607 DEBUG (( DEBUG_INFO
,
1608 "DataSource exiting, Status: %r\r\n",