+
+
+/**
+ Respond with the Exit page
+
+ @param [in] SocketFD The socket's file descriptor to add to the list.
+ @param [in] pPort The WSDT_PORT structure address
+ @param [out] pbDone Address to receive the request completion status
+
+ @retval EFI_SUCCESS The request was successfully processed
+
+**/
+EFI_STATUS
+ExitPage (
+ IN int SocketFD,
+ IN WSDT_PORT * pPort,
+ OUT BOOLEAN * pbDone
+ )
+{
+ EFI_STATUS Status;
+
+ DBG_ENTER ( );
+
+ //
+ // Send the Hello World page
+ //
+ for ( ; ; ) {
+ //
+ // Tell the web-server to exit
+ //
+ mWebServer.bRunning = FALSE;
+
+ //
+ // Send the page header
+ //
+ Status = HttpPageHeader ( SocketFD, pPort, L"Exit" );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Send the page body
+ //
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ "Exit
\r\n"
+ "\r\n"
+ " Exiting the web-server application.\r\n"
+ "
\r\n" );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Send the page trailer
+ //
+ Status = HttpPageTrailer ( SocketFD, pPort, pbDone );
+ break;
+ }
+
+ //
+ // Return the operation status
+ //
+ DBG_EXIT_STATUS ( Status );
+ return Status;
+}
diff --git a/AppPkg/Applications/Sockets/WebServer/HTTP.c b/AppPkg/Applications/Sockets/WebServer/HTTP.c
index 8487de751a..9a8bd70a9d 100644
--- a/AppPkg/Applications/Sockets/WebServer/HTTP.c
+++ b/AppPkg/Applications/Sockets/WebServer/HTTP.c
@@ -401,8 +401,8 @@ HttpPageTrailer (
int RetVal;
EFI_STATUS Status;
socklen_t LengthInBytes;
- struct sockaddr_in LocalAddress;
- struct sockaddr_in RemoteAddress;
+ struct sockaddr_in6 LocalAddress;
+ struct sockaddr_in6 RemoteAddress;
DBG_ENTER ( );
@@ -413,12 +413,13 @@ HttpPageTrailer (
LengthInBytes = sizeof ( LocalAddress );
RetVal = getsockname ( SocketFD, (struct sockaddr *)&LocalAddress, &LengthInBytes );
if ( 0 == RetVal ) {
+ LengthInBytes = sizeof ( LocalAddress );
RetVal = getpeername ( SocketFD, (struct sockaddr *)&RemoteAddress, &LengthInBytes );
if ( 0 == RetVal ) {
//
// Seperate the body from the trailer
//
- Status = HttpSendAnsiString ( SocketFD, pPort, "
\r\n" );
+ Status = HttpSendAnsiString ( SocketFD, pPort, "
\r\n" );
if ( EFI_ERROR ( Status )) {
break;
}
@@ -438,7 +439,7 @@ HttpPageTrailer (
if ( EFI_ERROR ( Status )) {
break;
}
- Status = HttpSendAnsiString ( SocketFD, pPort, "\r\n" );
+ Status = HttpSendAnsiString ( SocketFD, pPort, "
\r\n" );
if ( EFI_ERROR ( Status )) {
break;
}
@@ -1213,7 +1214,7 @@ HttpSendHexBits (
//
Digit = (UINT32)(( Value >> Shift ) & 0xf );
if ( 10 <= Digit ) {
- Digit += 'A' - '0' - 10;
+ Digit += 'a' - '0' - 10;
}
//
@@ -1274,7 +1275,7 @@ HttpSendHexValue (
//
Digit = (UINT32)(( Value >> Shift ) & 0xf );
if ( 10 <= Digit ) {
- Digit += 'A' - '0' - 10;
+ Digit += 'a' - '0' - 10;
}
//
@@ -1305,6 +1306,112 @@ HttpSendHexValue (
}
+/**
+ Output an IP6 address value to the HTML page
+
+ @param [in] SocketFD Socket file descriptor
+ @param [in] pPort The WSDT_PORT structure address
+ @param [in] Value Value to display
+ @param [in] bFirstValue TRUE if first value
+ @param [in] bLastValue TRUE if last value
+ @param [in] bZeroSuppression TRUE while zeros are being suppressed
+ @param [in] pbZeroSuppression Address to receive TRUE when zero suppression
+ has started, use NULL if next colon value not
+ needed.
+
+ @retval EFI_SUCCESS Successfully displayed the address
+**/
+EFI_STATUS
+HttpSendIp6Value (
+ IN int SocketFD,
+ IN WSDT_PORT * pPort,
+ IN UINT16 Value,
+ IN BOOLEAN bFirstValue,
+ IN BOOLEAN bLastValue,
+ IN BOOLEAN bZeroSuppression,
+ IN BOOLEAN * pbZeroSuppression
+ )
+{
+ BOOLEAN bZeroSuppressionStarting;
+ UINT32 Digit;
+ EFI_STATUS Status;
+
+ //
+ // Use break instead of goto
+ //
+ bZeroSuppressionStarting = FALSE;
+ Status = EFI_SUCCESS;
+ for ( ; ; ) {
+ //
+ // Display the leading colon if necessary
+ //
+ if ( bZeroSuppression && ( bLastValue || ( 0 != Value ))) {
+ Status = HttpSendByte ( SocketFD, pPort, ':' );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ }
+
+ //
+ // Skip over a series of zero values
+ //
+ bZeroSuppressionStarting = (BOOLEAN)( 0 == Value );
+ if ( !bZeroSuppressionStarting ) {
+ //
+ // Display the value
+ //
+ Digit = ( Value >> 4 ) & 0xf;
+ Status = HttpSendHexValue ( SocketFD,
+ pPort,
+ Digit );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Digit = Value & 0xf;
+ Status = HttpSendHexValue ( SocketFD,
+ pPort,
+ Digit );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Digit = ( Value >> 12 ) & 0xf;
+ Status = HttpSendHexValue ( SocketFD,
+ pPort,
+ Digit );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Digit = ( Value >> 8 ) & 0xf;
+ Status = HttpSendHexValue ( SocketFD,
+ pPort,
+ Digit );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ }
+
+ //
+ // Display the trailing colon if necessary
+ //
+ if (( !bLastValue ) && ( bFirstValue || ( 0 != Value ))) {
+ Status = HttpSendByte ( SocketFD, pPort, ':' );
+ }
+ break;
+ }
+
+ //
+ // Return the next colon display
+ if ( NULL != pbZeroSuppression ) {
+ *pbZeroSuppression = bZeroSuppressionStarting;
+ }
+
+ //
+ // Return the operation status
+ //
+ return Status;
+}
+
+
/**
Output an IP address to the HTML page
@@ -1318,41 +1425,109 @@ EFI_STATUS
HttpSendIpAddress (
IN int SocketFD,
IN WSDT_PORT * pPort,
- IN struct sockaddr_in * pAddress
+ IN struct sockaddr_in6 * pAddress
)
{
+ BOOLEAN bZeroSuppression;
+ UINT32 Index;
+ struct sockaddr_in * pIpv4;
+ struct sockaddr_in6 * pIpv6;
+ UINT16 PortNumber;
EFI_STATUS Status;
//
- // Output the IPv4 address
+ // Use break instead of goto
//
- Status = HttpSendValue ( SocketFD, pPort, (UINT8)pAddress->sin_addr.s_addr );
- if ( !EFI_ERROR ( Status )) {
- Status = HttpSendByte ( SocketFD, pPort, '.' );
- if ( !EFI_ERROR ( Status )) {
- Status = HttpSendValue ( SocketFD, pPort, (UINT8)( pAddress->sin_addr.s_addr >> 8 ));
- if ( !EFI_ERROR ( Status )) {
- Status = HttpSendByte ( SocketFD, pPort, '.' );
- if ( !EFI_ERROR ( Status )) {
- Status = HttpSendValue ( SocketFD, pPort, (UINT8)( pAddress->sin_addr.s_addr >> 16 ));
- if ( !EFI_ERROR ( Status )) {
- Status = HttpSendByte ( SocketFD, pPort, '.' );
- if ( !EFI_ERROR ( Status )) {
- Status = HttpSendValue ( SocketFD, pPort, (UINT8)( pAddress->sin_addr.s_addr >> 24 ));
- if ( !EFI_ERROR ( Status )) {
- //
- // Output the port number
- //
- Status = HttpSendByte ( SocketFD, pPort, ':' );
- if ( !EFI_ERROR ( Status )) {
- Status = HttpSendValue ( SocketFD, pPort, htons ( pAddress->sin_port ));
- }
- }
- }
- }
+ for ( ; ; ) {
+ //
+ // Determine the type of address
+ //
+ if ( AF_INET6 == pAddress->sin6_family ) {
+ pIpv6 = pAddress;
+
+ //
+ // Display the address in RFC2732 format
+ //
+ bZeroSuppression = FALSE;
+ Status = HttpSendByte ( SocketFD, pPort, '[' );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ for ( Index = 0; 8 > Index; Index++ ) {
+ Status = HttpSendIp6Value ( SocketFD,
+ pPort,
+ pIpv6->sin6_addr.__u6_addr.__u6_addr16[ Index ],
+ (BOOLEAN)( 0 == Index ),
+ (BOOLEAN)( 7 == Index ),
+ bZeroSuppression,
+ &bZeroSuppression );
+ if ( EFI_ERROR ( Status )) {
+ break;
}
}
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Separate the port number
+ //
+ Status = HttpSendByte ( SocketFD, pPort, ']' );
+
+ //
+ // Get the port number
+ //
+ PortNumber = pIpv6->sin6_port;
}
+ else {
+ //
+ // Output the IPv4 address
+ //
+ pIpv4 = (struct sockaddr_in *)pAddress;
+ Status = HttpSendValue ( SocketFD, pPort, (UINT8)pIpv4->sin_addr.s_addr );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = HttpSendByte ( SocketFD, pPort, '.' );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = HttpSendValue ( SocketFD, pPort, (UINT8)( pIpv4->sin_addr.s_addr >> 8 ));
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = HttpSendByte ( SocketFD, pPort, '.' );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = HttpSendValue ( SocketFD, pPort, (UINT8)( pIpv4->sin_addr.s_addr >> 16 ));
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = HttpSendByte ( SocketFD, pPort, '.' );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = HttpSendValue ( SocketFD, pPort, (UINT8)( pIpv4->sin_addr.s_addr >> 24 ));
+
+ //
+ // Get the port number
+ //
+ PortNumber = pIpv4->sin_port;
+ }
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Display the port number
+ //
+ Status = HttpSendByte ( SocketFD, pPort, ':' );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = HttpSendValue ( SocketFD, pPort, htons ( PortNumber ));
+ break;
}
//
diff --git a/AppPkg/Applications/Sockets/WebServer/PageList.c b/AppPkg/Applications/Sockets/WebServer/PageList.c
index f26ab0fdbb..98927e8e1d 100644
--- a/AppPkg/Applications/Sockets/WebServer/PageList.c
+++ b/AppPkg/Applications/Sockets/WebServer/PageList.c
@@ -44,10 +44,12 @@ CONST DT_PAGE mPageList[] = {
{ L"/DhcpOptions", DhcpOptionsPage, L"DHCP Options" }, ///< Display the DHCP options
{ PAGE_ACPI_DSDT, AcpiDsdtPage, L"DSDT - Differentiated System Description Table" }, ///< Format DSDT
{ PAGE_DXE_SERVICES_TABLE, DxeServicesTablePage, L"DXE Services Table" }, ///< Format DXE services table
+ { L"/Exit", ExitPage, L"Exit the web server" }, ///< Exit the web server application
{ PAGE_ACPI_FADT, AcpiFadtPage, L"FADT - Fixed ACPI Description Table" }, ///< Format FADT
{ L"/Firmware", FirmwarePage, L"Firmware" }, ///< Firmware status
{ L"/Handles", HandlePage, L"Display handles and associated protocol GUIDs" }, ///< Handle database page
{ L"/Hello", HelloPage, L"Hello World" }, ///< Hello world page
+ { L"/Ports", PortsPage, L"Display web-server ports" },///< Web-server ports page
{ L"/Reboot", RebootPage, L"Reboot the sytem" }, ///< Reboot page
{ PAGE_ACPI_RSDP_10B, AcpiRsdp10Page, L"RSDP 1.0b - ACPI Root System Description Pointer" }, ///< Format RSDP 1.0b table
{ PAGE_ACPI_RSDP_30, AcpiRsdp30Page, L"RSDP 3.0 - ACPI Root System Description Pointer" }, ///< Format RSDP 3.0 table
diff --git a/AppPkg/Applications/Sockets/WebServer/Ports.c b/AppPkg/Applications/Sockets/WebServer/Ports.c
new file mode 100644
index 0000000000..e9190bf68d
--- /dev/null
+++ b/AppPkg/Applications/Sockets/WebServer/Ports.c
@@ -0,0 +1,146 @@
+/*++
+ This file contains an 'Intel UEFI Application' and is
+ licensed for Intel CPUs and chipsets under the terms of your
+ license agreement with Intel or your vendor. This file may
+ be modified by the user, subject to additional terms of the
+ license agreement
+--*/
+/*++
+
+Copyright (c) 2011 Intel Corporation. All rights reserved
+This software and associated documentation (if any) is furnished
+under a license and may only be used or copied in accordance
+with the terms of the license. Except as permitted by such
+license, no part of this software or documentation may be
+reproduced, stored in a retrieval system, or transmitted in any
+form or by any means without the express written consent of
+Intel Corporation.
+
+--*/
+
+/** @file
+ Ports response page
+
+**/
+
+#include
+
+
+/**
+ Respond with the Ports page
+
+ @param [in] SocketFD The socket's file descriptor to add to the list.
+ @param [in] pPort The WSDT_PORT structure address
+ @param [out] pbDone Address to receive the request completion status
+
+ @retval EFI_SUCCESS The request was successfully processed
+
+**/
+EFI_STATUS
+PortsPage (
+ IN int SocketFD,
+ IN WSDT_PORT * pPort,
+ OUT BOOLEAN * pbDone
+ )
+{
+ socklen_t AddressLength;
+ struct sockaddr_in6 LocalAddress;
+ DT_WEB_SERVER * pWebServer;
+ EFI_STATUS Status;
+
+ DBG_ENTER ( );
+
+ //
+ // Send the Hello World page
+ //
+ pWebServer = &mWebServer;
+ for ( ; ; ) {
+ //
+ // Send the page header
+ //
+ Status = HttpPageHeader ( SocketFD, pPort, L"Ports" );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Send the page body
+ //
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ "Web-Server Ports
\r\n" );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Check for TCP v4
+ //
+ if ( -1 != pWebServer->HttpListenPort ) {
+ AddressLength = sizeof ( LocalAddress );
+ if ( 0 == getsockname ( pWebServer->HttpListenPort,
+ (struct sockaddr *)&LocalAddress,
+ &AddressLength )) {
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ "Tcp4
\r\n" );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ }
+ }
+
+ //
+ // Check for TCP v6
+ //
+ if ( -1 != pWebServer->HttpListenPort6 ) {
+ AddressLength = sizeof ( LocalAddress );
+ if ( 0 == getsockname ( pWebServer->HttpListenPort6,
+ (struct sockaddr *)&LocalAddress,
+ &AddressLength )) {
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ "Tcp6
\r\n" );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ }
+ }
+
+ //
+ // Send the page trailer
+ //
+ Status = HttpPageTrailer ( SocketFD, pPort, pbDone );
+ break;
+ }
+
+ //
+ // Return the operation status
+ //
+ DBG_EXIT_STATUS ( Status );
+ return Status;
+}
diff --git a/AppPkg/Applications/Sockets/WebServer/WebServer.c b/AppPkg/Applications/Sockets/WebServer/WebServer.c
index 5c73bfe8f7..00f8633efb 100644
--- a/AppPkg/Applications/Sockets/WebServer/WebServer.c
+++ b/AppPkg/Applications/Sockets/WebServer/WebServer.c
@@ -337,7 +337,7 @@ PortWork (
size_t LengthInBytes;
int NewSocket;
EFI_STATUS OpStatus;
- struct sockaddr RemoteAddress;
+ struct sockaddr_in6 RemoteAddress;
socklen_t RemoteAddressLength;
EFI_STATUS Status;
@@ -355,14 +355,15 @@ PortWork (
//
// Determine if this is a connection attempt
//
- if ( SocketFD == pWebServer->HttpListenPort ) {
+ if (( SocketFD == pWebServer->HttpListenPort )
+ || ( SocketFD == pWebServer->HttpListenPort6 )) {
//
// Handle connection attempts
// Accepts arrive as read events
//
RemoteAddressLength = sizeof ( RemoteAddress );
NewSocket = accept ( SocketFD,
- &RemoteAddress,
+ (struct sockaddr *)&RemoteAddress,
&RemoteAddressLength );
if ( -1 != NewSocket ) {
if ( 0 != NewSocket ) {
@@ -561,9 +562,9 @@ SocketPoll (
/**
- Create the HTTP port for the web server
+ Create an HTTP port for the web server
- This routine polls the network layer to create the HTTP port for the
+ This routine polls the network layer to create an HTTP port for the
web server. More than one attempt may be necessary since it may take
some time to get the IP address and initialize the upper layers of
the network stack.
@@ -572,195 +573,93 @@ SocketPoll (
coming and going of the network connections until the last network
connection is broken.
- @param [in] pWebServer The web server control structure address.
+ @param [in] pWebServer The web server control structure address.
+ @param [in] AddressFamily Address family for the network connection
+ @param [in] Protocol Protocol to use for the network connection
+ @param [in] HttpPort Port number for the HTTP connection
+ @param [out] pPort Address of the port
**/
VOID
-WebServerTimer (
- IN DT_WEB_SERVER * pWebServer
+WebServerListen (
+ IN DT_WEB_SERVER * pWebServer,
+ IN sa_family_t AddressFamily,
+ IN int Protocol,
+ IN UINT16 HttpPort,
+ OUT int * pPort
)
{
- UINT16 HttpPort;
- struct sockaddr_in WebServerAddress;
+ union {
+ struct sockaddr_in v4;
+ struct sockaddr_in6 v6;
+ } WebServerAddress;
int SocketStatus;
EFI_STATUS Status;
- DEBUG (( DEBUG_SERVER_TIMER, "Entering WebServerTimer\r\n" ));
+ DEBUG (( DEBUG_SERVER_LISTEN, "Entering WebServerListen\r\n" ));
//
- // Open the HTTP port on the server
+ // Attempt to create the socket for the web server
//
- do {
- do {
- //
- // Complete the client operations
- //
- SocketPoll ( pWebServer );
-
- //
- // Wait for a while
- //
- Status = gBS->CheckEvent ( pWebServer->TimerEvent );
- } while ( EFI_SUCCESS != Status );
+ * pPort = socket ( AddressFamily, SOCK_STREAM, Protocol );
+ if ( -1 != *pPort ) {
+ //
+ // Build the socket address
+ //
+ ZeroMem ( &WebServerAddress, sizeof ( WebServerAddress ));
+ if ( AF_INET == AddressFamily ) {
+ WebServerAddress.v4.sin_len = sizeof ( WebServerAddress.v4 );
+ WebServerAddress.v4.sin_family = AddressFamily;
+ WebServerAddress.v4.sin_port = htons ( HttpPort );
+ }
+ else {
+ WebServerAddress.v6.sin6_len = sizeof ( WebServerAddress.v6 );
+ WebServerAddress.v6.sin6_family = AddressFamily;
+ WebServerAddress.v6.sin6_port = htons ( HttpPort );
+ WebServerAddress.v6.sin6_scope_id = __IPV6_ADDR_SCOPE_GLOBAL;
+ }
//
- // Attempt to create the socket for the web server
+ // Bind the socket to the HTTP port
//
- pWebServer->HttpListenPort = socket ( AF_INET,
- SOCK_STREAM,
- IPPROTO_TCP );
- if ( -1 != pWebServer->HttpListenPort ) {
+ SocketStatus = bind ( *pPort,
+ (struct sockaddr *) &WebServerAddress,
+ WebServerAddress.v4.sin_len );
+ if ( -1 != SocketStatus ) {
//
- // Set the socket address
+ // Enable connections to the HTTP port
//
- ZeroMem ( &WebServerAddress, sizeof ( WebServerAddress ));
- HttpPort = PcdGet16 ( WebServer_HttpPort );
- DEBUG (( DEBUG_HTTP_PORT,
- "HTTP Port: %d\r\n",
- HttpPort ));
- WebServerAddress.sin_len = sizeof ( WebServerAddress );
- WebServerAddress.sin_family = AF_INET;
- WebServerAddress.sin_addr.s_addr = INADDR_ANY;
- WebServerAddress.sin_port = htons ( HttpPort );
-
- //
- // Bind the socket to the HTTP port
- //
- SocketStatus = bind ( pWebServer->HttpListenPort,
- (struct sockaddr *) &WebServerAddress,
- WebServerAddress.sin_len );
+ SocketStatus = listen ( *pPort, SOMAXCONN );
if ( -1 != SocketStatus ) {
//
- // Enable connections to the HTTP port
+ // Add the HTTP port to the list of ports to poll
//
- SocketStatus = listen ( pWebServer->HttpListenPort,
- SOMAXCONN );
- }
-
- //
- // Release the socket if necessary
- //
- if ( -1 == SocketStatus ) {
- close ( pWebServer->HttpListenPort );
- pWebServer->HttpListenPort = -1;
+ Status = PortAdd ( pWebServer, *pPort );
+ if ( EFI_ERROR ( Status )) {
+ SocketStatus = -1;
+ }
+ else {
+ DEBUG (( DEBUG_PORT_WORK,
+ "Listening on Tcp%d:%d\r\n",
+ ( AF_INET == AddressFamily ) ? 4 : 6,
+ HttpPort ));
+ }
}
}
//
- // Wait until the socket is open
+ // Release the socket if necessary
//
- }while ( -1 == pWebServer->HttpListenPort );
-
- DEBUG (( DEBUG_SERVER_TIMER, "Exiting WebServerTimer\r\n" ));
-}
-
-
-/**
- Start the web server port creation timer
-
- @param [in] pWebServer The web server control structure address.
-
- @retval EFI_SUCCESS The timer was successfully started.
- @retval EFI_ALREADY_STARTED The timer is already running.
- @retval Other The timer failed to start.
-
-**/
-EFI_STATUS
-WebServerTimerStart (
- IN DT_WEB_SERVER * pWebServer
- )
-{
- EFI_STATUS Status;
- UINT64 TriggerTime;
-
- DBG_ENTER ( );
-
- //
- // Assume the timer is already running
- //
- Status = EFI_ALREADY_STARTED;
- if ( !pWebServer->bTimerRunning ) {
- //
- // Compute the poll interval
- //
- TriggerTime = HTTP_PORT_POLL_DELAY * ( 1000 * 10 );
- Status = gBS->SetTimer ( pWebServer->TimerEvent,
- TimerPeriodic,
- TriggerTime );
- if ( !EFI_ERROR ( Status )) {
- DEBUG (( DEBUG_HTTP_PORT, "HTTP port timer started\r\n" ));
-
- //
- // Mark the timer running
- //
- pWebServer->bTimerRunning = TRUE;
- }
- else {
- DEBUG (( DEBUG_ERROR | DEBUG_HTTP_PORT,
- "ERROR - Failed to start HTTP port timer, Status: %r\r\n",
- Status ));
+ if ( -1 == SocketStatus ) {
+ close ( *pPort );
+ *pPort = -1;
}
}
- //
- // Return the operation status
- //
- DBG_EXIT_STATUS ( Status );
- return Status;
+ DEBUG (( DEBUG_SERVER_LISTEN, "Exiting WebServerListen\r\n" ));
}
-/**
- Stop the web server port creation timer
-
- @param [in] pWebServer The web server control structure address.
-
- @retval EFI_SUCCESS The HTTP port timer is stopped
- @retval Other Failed to stop the HTTP port timer
-
-**/
-EFI_STATUS
-WebServerTimerStop (
- IN DT_WEB_SERVER * pWebServer
- )
-{
- EFI_STATUS Status;
-
- DBG_ENTER ( );
-
- //
- // Assume the timer is stopped
- //
- Status = EFI_SUCCESS;
- if ( pWebServer->bTimerRunning ) {
- //
- // Stop the port creation polling
- //
- Status = gBS->SetTimer ( pWebServer->TimerEvent,
- TimerCancel,
- 0 );
- if ( !EFI_ERROR ( Status )) {
- DEBUG (( DEBUG_HTTP_PORT, "HTTP port timer stopped\r\n" ));
-
- //
- // Mark the timer stopped
- //
- pWebServer->bTimerRunning = FALSE;
- }
- else {
- DEBUG (( DEBUG_ERROR | DEBUG_HTTP_PORT,
- "ERROR - Failed to stop HTTP port timer, Status: %r\r\n",
- Status ));
- }
- }
-
- //
- // Return the operation status
- //
- DBG_EXIT_STATUS ( Status );
- return Status;
-}
-
/**
Entry point for the web server application.
@@ -776,8 +675,19 @@ main (
IN char **Argv
)
{
+ UINT16 HttpPort;
+ UINTN Index;
DT_WEB_SERVER * pWebServer;
EFI_STATUS Status;
+ UINT64 TriggerTime;
+
+ //
+ // Get the HTTP port
+ //
+ HttpPort = PcdGet16 ( WebServer_HttpPort );
+ DEBUG (( DEBUG_HTTP_PORT,
+ "HTTP Port: %d\r\n",
+ HttpPort ));
//
// Create a timer event to start HTTP port
@@ -789,12 +699,18 @@ main (
NULL,
&pWebServer->TimerEvent );
if ( !EFI_ERROR ( Status )) {
- Status = WebServerTimerStart ( pWebServer );
+ TriggerTime = HTTP_PORT_POLL_DELAY * ( 1000 * 10 );
+ Status = gBS->SetTimer ( pWebServer->TimerEvent,
+ TimerPeriodic,
+ TriggerTime );
if ( !EFI_ERROR ( Status )) {
//
// Run the web server forever
//
- for ( ; ; ) {
+ pWebServer->HttpListenPort = -1;
+ pWebServer->HttpListenPort6 = -1;
+ pWebServer->bRunning = TRUE;
+ do {
//
// Poll the network layer to create the HTTP port
// for the web server. More than one attempt may
@@ -802,45 +718,72 @@ main (
// the IP address and initialize the upper layers
// of the network stack.
//
- WebServerTimer ( pWebServer );
-
- //
- // Add the HTTP port to the list of ports
- //
- Status = PortAdd ( pWebServer, pWebServer->HttpListenPort );
- if ( !EFI_ERROR ( Status )) {
- //
- // Poll the sockets for activity
- //
+ if (( -1 == pWebServer->HttpListenPort )
+ || ( -1 == pWebServer->HttpListenPort6 )) {
do {
- SocketPoll ( pWebServer );
- } while ( -1 != pWebServer->HttpListenPort );
+ //
+ // Wait a while before polling for a connection
+ //
+ if ( EFI_SUCCESS != gBS->CheckEvent ( pWebServer->TimerEvent )) {
+ if ( 0 != pWebServer->Entries ) {
+ break;
+ }
+ gBS->WaitForEvent ( 1, &pWebServer->TimerEvent, &Index );
+ }
- //
- // The HTTP port failed the accept and was closed
- //
+ //
+ // Poll for a network connection
+ //
+ if ( -1 == pWebServer->HttpListenPort ) {
+ WebServerListen ( pWebServer,
+ AF_INET,
+ IPPROTO_TCP,
+ HttpPort,
+ &pWebServer->HttpListenPort );
+ }
+ if ( -1 == pWebServer->HttpListenPort6 ) {
+ WebServerListen ( pWebServer,
+ AF_INET6,
+ IPPROTO_TCP,
+ HttpPort,
+ &pWebServer->HttpListenPort6 );
+ }
+
+ //
+ // Continue polling while both network connections are
+ // not present
+ //
+ } while ( 0 == pWebServer->Entries );
}
//
- // Close the HTTP port if necessary
+ // Poll the sockets for activity while both network
+ // connections are connected
//
- if ( -1 != pWebServer->HttpListenPort ) {
- close ( pWebServer->HttpListenPort );
- pWebServer->HttpListenPort = -1;
- }
-//
-// TODO: Remove the following test code
-// Exit when the network connection is broken
-//
-break;
- }
+ do {
+ SocketPoll ( pWebServer );
+ } while ( pWebServer->bRunning
+ && ( -1 != pWebServer->HttpListenPort )
+ && ( -1 != pWebServer->HttpListenPort6 ));
+
+ //
+ // Continue polling the network connections until both
+ // TCP4 and TCP6 are connected
+ //
+ } while ( pWebServer->bRunning );
//
- // Done with the timer event
+ // Stop the timer
//
- WebServerTimerStop ( pWebServer );
- Status = gBS->CloseEvent ( pWebServer->TimerEvent );
+ gBS->SetTimer ( pWebServer->TimerEvent,
+ TimerCancel,
+ 0 );
}
+
+ //
+ // Done with the timer event
+ //
+ gBS->CloseEvent ( pWebServer->TimerEvent );
}
//
diff --git a/AppPkg/Applications/Sockets/WebServer/WebServer.h b/AppPkg/Applications/Sockets/WebServer/WebServer.h
index 0eee114832..a5dcea4969 100644
--- a/AppPkg/Applications/Sockets/WebServer/WebServer.h
+++ b/AppPkg/Applications/Sockets/WebServer/WebServer.h
@@ -86,7 +86,7 @@
#define DEBUG_SOCKET_POLL 0x00080000 ///< Display the socket poll messages
#define DEBUG_PORT_WORK 0x00040000 ///< Display the port work messages
-#define DEBUG_SERVER_TIMER 0x00020000 ///< Display the socket poll messages
+#define DEBUG_SERVER_LISTEN 0x00020000 ///< Display the socket poll messages
#define DEBUG_HTTP_PORT 0x00010000 ///< Display HTTP port related messages
#define DEBUG_REQUEST 0x00008000 ///< Display the HTTP request messages
@@ -173,9 +173,10 @@ typedef struct {
//
// HTTP port management
//
- BOOLEAN bTimerRunning; ///< Port creation timer status
+ BOOLEAN bRunning; ///< Web server running
EFI_EVENT TimerEvent; ///< Timer to open HTTP port
- int HttpListenPort; ///< File descriptor for the HTTP listen port
+ int HttpListenPort; ///< File descriptor for the HTTP listen port over TCP4
+ int HttpListenPort6; ///< File descriptor for the HTTP listen port over TCP6
//
// Client port management
@@ -377,6 +378,23 @@ DxeServicesTablePage (
OUT BOOLEAN * pbDone
);
+/**
+ Respond with the Exit page
+
+ @param [in] SocketFD The socket's file descriptor to add to the list.
+ @param [in] pPort The WSDT_PORT structure address
+ @param [out] pbDone Address to receive the request completion status
+
+ @retval EFI_SUCCESS The request was successfully processed
+
+**/
+EFI_STATUS
+ExitPage (
+ IN int SocketFD,
+ IN WSDT_PORT * pPort,
+ OUT BOOLEAN * pbDone
+ );
+
/**
Respond with the firmware status
@@ -445,6 +463,23 @@ IndexPage (
OUT BOOLEAN * pbDone
);
+/**
+ Respond with the Ports page
+
+ @param [in] SocketFD The socket's file descriptor to add to the list.
+ @param [in] pPort The WSDT_PORT structure address
+ @param [out] pbDone Address to receive the request completion status
+
+ @retval EFI_SUCCESS The request was successfully processed
+
+**/
+EFI_STATUS
+PortsPage (
+ IN int SocketFD,
+ IN WSDT_PORT * pPort,
+ OUT BOOLEAN * pbDone
+ );
+
/**
Page to reboot the system
@@ -723,7 +758,7 @@ EFI_STATUS
HttpSendIpAddress (
IN int SocketFD,
IN WSDT_PORT * pPort,
- IN struct sockaddr_in * pAddress
+ IN struct sockaddr_in6 * pAddress
);
/**
diff --git a/AppPkg/Applications/Sockets/WebServer/WebServer.inf b/AppPkg/Applications/Sockets/WebServer/WebServer.inf
index 308e4bfff2..c250007295 100644
--- a/AppPkg/Applications/Sockets/WebServer/WebServer.inf
+++ b/AppPkg/Applications/Sockets/WebServer/WebServer.inf
@@ -8,7 +8,7 @@
# license agreement
#
#
-# Copyright (c) 20011 Intel Corporation. All rights reserved
+# Copyright (c) 2011 Intel Corporation. All rights reserved
# This software and associated documentation (if any) is furnished
# under a license and may only be used or copied in accordance
# with the terms of the license. Except as permitted by such
@@ -40,12 +40,14 @@
ConfigurationTable.c
DhcpOptions.c
DxeServicesTable.c
+ Exit.c
Firmware.c
Handles.c
Hello.c
HTTP.c
Index.c
PageList.c
+ Ports.c
Reboot.c
RuntimeServicesTable.c
SystemTable.c
@@ -53,10 +55,10 @@
[Pcd]
- gStdLibTokenSpaceGuid.WebServer_HttpPort
-
+ gAppPkgTokenSpaceGuid.WebServer_HttpPort
[Packages]
+ AppPkg/AppPkg.dec
MdePkg/MdePkg.dec
MdeModulePkg/MdeModulePkg.dec
ShellPkg/ShellPkg.dec
@@ -68,14 +70,14 @@
BsdSocketLib
DebugLib
DevShell
-# EfiSocketLib
+ EfiSocketLib
LibC
ShellLib
ShellCEntryLib
UefiBootServicesTableLib
UefiLib
UefiRuntimeServicesTableLib
- UseSocketDxe
+# UseSocketDxe
[Guids]
gEfiAcpi10TableGuid