Merged socket development branch:

* Add TCPv6 support to DataSink
* Add TCPv6 support to DataSource
* Add GetAddrInfo test application
* Add GetNameInfo test application
* Fixed copyright date
* Completed TFTP server - now downloads files from local directory
* Added ports and exit pages to web server
* Made PCD values package specific

Signed-off-by: lpleahy

git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@13003 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
lpleahy
2012-02-09 19:18:06 +00:00
parent 3bdf9aae5f
commit f6e5cdd5cf
34 changed files with 3524 additions and 1372 deletions

View File

@@ -0,0 +1,92 @@
/*++
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
Exit response page
**/
#include <WebServer.h>
/**
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,
"<h1>Exit</h1>\r\n"
"<p>\r\n"
" Exiting the web-server application.\r\n"
"</p>\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;
}

View File

@@ -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, " <hr>\r\n" );
Status = HttpSendAnsiString ( SocketFD, pPort, " <hr>\r\n<code>" );
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, "</code>\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;
}
//

View File

@@ -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

View File

@@ -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 <WebServer.h>
/**
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,
"<h1>Web-Server Ports</h1>\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,
"<a href=\"http://" );
if ( EFI_ERROR ( Status )) {
break;
}
Status = HttpSendIpAddress ( SocketFD,
pPort,
&LocalAddress );
if ( EFI_ERROR ( Status )) {
break;
}
Status = HttpSendAnsiString ( SocketFD,
pPort,
"\">Tcp4</a><br>\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,
"<a href=\"http://" );
if ( EFI_ERROR ( Status )) {
break;
}
Status = HttpSendIpAddress ( SocketFD,
pPort,
&LocalAddress );
if ( EFI_ERROR ( Status )) {
break;
}
Status = HttpSendAnsiString ( SocketFD,
pPort,
"\">Tcp6</a><br>\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;
}

View File

@@ -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 );
}
//

View File

@@ -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
);
/**

View File

@@ -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