hikey: Add UEFI sources for reference
UEFI needs to be built outside Android build system.
Please follow the instructions in README.
The sources correspond to:
https://github.com/96boards/edk2/commit/14eae0c12e71fd33c4c0fc51e4475e8db02566cf
https://github.com/96boards/arm-trusted-firmware/commit/e9b4909dcd75fc4ae7041cfb83d28ab9adb7afdf
https://github.com/96boards/l-loader/commit/6b784ad5c4ab00e2b1c6f53cd5f74054e5d00a78
https://git.linaro.org/uefi/uefi-tools.git/commit/abe618f8ab72034fff1ce46c9c006a2c6bd40a7e
Change-Id: Ieeefdb63e673e0c8e64e0a1f02c7bddc63b2c7fb
Signed-off-by: Vishal Bhoj <vishal.bhoj@linaro.org>
diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/DataSink/DataSink.c b/uefi/linaro-edk2/AppPkg/Applications/Sockets/DataSink/DataSink.c
new file mode 100644
index 0000000..14b2fd1
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/DataSink/DataSink.c
@@ -0,0 +1,1287 @@
+/** @file
+ Data source for network testing.
+
+ Copyright (c) 2011-2012, Intel Corporation
+ All rights reserved. This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <errno.h>
+#include <Uefi.h>
+
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/PcdLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiLib.h>
+
+#include <netinet/in.h>
+
+#include <sys/EfiSysCall.h>
+#include <sys/poll.h>
+#include <sys/socket.h>
+
+
+#define DATA_SAMPLE_SHIFT 5 ///< Shift for number of samples
+#define MAX_CONNECTIONS ( 1 + 16 ) ///< Maximum number of client connections
+#define RANGE_SWITCH ( 1024 * 1024 ) ///< Switch display ranges
+#define DATA_RATE_UPDATE_SHIFT 2 ///< 2n seconds between updates
+#define AVERAGE_SHIFT_COUNT ( 6 - DATA_RATE_UPDATE_SHIFT ) ///< 2n samples in average
+#define DATA_SAMPLES ( 1 << DATA_SAMPLE_SHIFT ) ///< Number of samples
+
+#define TPL_DATASINK TPL_CALLBACK ///< Synchronization TPL
+
+#define PACKET_SIZE 1448 ///< Size of data packets
+#define DATA_BUFFER_SIZE (( 65536 / PACKET_SIZE ) * PACKET_SIZE ) ///< Buffer size in bytes
+
+typedef struct _DT_PORT {
+ UINT64 BytesTotal;
+ struct sockaddr_in6 IpAddress;
+ UINT32 In;
+ UINT32 Samples;
+ UINT64 BytesReceived[ DATA_SAMPLES ];
+} DT_PORT;
+
+volatile BOOLEAN bTick;
+BOOLEAN bTimerRunning;
+struct sockaddr_in6 LocalAddress;
+EFI_EVENT pTimer;
+int ListenSocket;
+UINT8 Buffer[ DATA_BUFFER_SIZE ];
+struct pollfd PollFd[ MAX_CONNECTIONS ];
+DT_PORT Port[ MAX_CONNECTIONS ];
+nfds_t MaxPort;
+
+
+//
+// Forward routine declarations
+//
+EFI_STATUS TimerStart ( UINTN Milliseconds );
+
+
+/**
+ Check for control C entered at console
+
+ @retval EFI_SUCCESS Control C not entered
+ @retval EFI_ABORTED Control C entered
+**/
+EFI_STATUS
+ControlCCheck (
+ )
+{
+ EFI_STATUS Status;
+
+ //
+ // Assume no user intervention
+ //
+ Status = EFI_SUCCESS;
+
+ //
+ // Display user stop request
+ //
+ if ( EFI_ERROR ( Status )) {
+ DEBUG (( DEBUG_INFO,
+ "User stop request!\r\n" ));
+ }
+
+ //
+ // Return the check status
+ //
+ return Status;
+}
+
+
+/**
+ Accept a socket connection
+
+ @retval EFI_SUCCESS The application is running normally
+ @retval EFI_NOT_STARTED Error with the listen socket
+ @retval Other The user stopped the application
+**/
+EFI_STATUS
+SocketAccept (
+ )
+{
+ INT32 SocketStatus;
+ EFI_STATUS Status;
+ INTN Index;
+
+ //
+ // Assume failure
+ //
+ Status = EFI_DEVICE_ERROR;
+
+ //
+ // Bind to the local address
+ //
+ SocketStatus = bind ( ListenSocket,
+ (struct sockaddr *) &LocalAddress,
+ LocalAddress.sin6_len );
+ if ( 0 == SocketStatus ) {
+ //
+ // Start listening on the local socket
+ //
+ SocketStatus = listen ( ListenSocket, 5 );
+ if ( 0 == SocketStatus ) {
+ //
+ // Local socket in the listen state
+ //
+ Status = EFI_SUCCESS;
+
+ //
+ // Allocate a port
+ //
+ Index = MaxPort++;
+ PollFd[ Index ].fd = ListenSocket;
+ PollFd[ Index ].events = POLLRDNORM | POLLHUP;
+ PollFd[ Index ].revents = 0;
+ ZeroMem ( &Port[ Index ], sizeof ( Port[ Index ]));
+ }
+ }
+
+ //
+ // Return the operation status
+ //
+ return Status;
+}
+
+
+/**
+ Close the socket
+
+ @retval EFI_SUCCESS The application is running normally
+ @retval Other The user stopped the application
+**/
+EFI_STATUS
+SocketClose (
+ )
+{
+ INT32 CloseStatus;
+ EFI_STATUS Status;
+
+ //
+ // Determine if the socket is open
+ //
+ Status = EFI_DEVICE_ERROR;
+ if ( -1 != ListenSocket ) {
+ //
+ // Attempt to close the socket
+ //
+ CloseStatus = close ( ListenSocket );
+ if ( 0 == CloseStatus ) {
+ DEBUG (( DEBUG_INFO,
+ "0x%08x: Socket closed\r\n",
+ ListenSocket ));
+ ListenSocket = -1;
+ Status = EFI_SUCCESS;
+ }
+ else {
+ DEBUG (( DEBUG_ERROR,
+ "ERROR: Failed to close socket, errno: %d\r\n",
+ errno ));
+ }
+ }
+
+ //
+ // Return the operation status
+ //
+ return Status;
+}
+
+
+/**
+ Create the socket
+
+ @param [in] Family Network family, AF_INET or AF_INET6
+
+ @retval EFI_SUCCESS The application is running normally
+ @retval Other The user stopped the application
+**/
+EFI_STATUS
+SocketNew (
+ sa_family_t Family
+ )
+{
+ EFI_STATUS Status;
+
+ //
+ // Get the port number
+ //
+ ZeroMem ( &LocalAddress, sizeof ( LocalAddress ));
+ LocalAddress.sin6_len = sizeof ( LocalAddress );
+ LocalAddress.sin6_family = Family;
+ LocalAddress.sin6_port = htons ( PcdGet16 ( DataSource_Port ));
+
+ //
+ // Loop creating the socket
+ //
+ DEBUG (( DEBUG_INFO,
+ "Creating the socket\r\n" ));
+
+ //
+ // Check for user stop request
+ //
+ Status = ControlCCheck ( );
+ if ( !EFI_ERROR ( Status )) {
+ //
+ // Attempt to create the socket
+ //
+ ListenSocket = socket ( LocalAddress.sin6_family,
+ SOCK_STREAM,
+ IPPROTO_TCP );
+ if ( -1 != ListenSocket ) {
+ DEBUG (( DEBUG_INFO,
+ "0x%08x: Socket created\r\n",
+ ListenSocket ));
+ }
+ else {
+ Status = EFI_NOT_STARTED;
+ }
+ }
+
+ //
+ // Return the operation status
+ //
+ return Status;
+}
+
+
+/**
+ Poll the socket for more work
+
+ @retval EFI_SUCCESS The application is running normally
+ @retval EFI_NOT_STARTED Listen socket error
+ @retval Other The user stopped the application
+**/
+EFI_STATUS
+SocketPoll (
+ )
+{
+ BOOLEAN bRemoveSocket;
+ BOOLEAN bListenError;
+ size_t BytesReceived;
+ int CloseStatus;
+ nfds_t Entry;
+ INTN EntryPrevious;
+ int FdCount;
+ nfds_t Index;
+ socklen_t LengthInBytes;
+ struct sockaddr_in * pPortIpAddress4;
+ struct sockaddr_in6 * pPortIpAddress6;
+ struct sockaddr_in * pRemoteAddress4;
+ struct sockaddr_in6 * pRemoteAddress6;
+ struct sockaddr_in6 RemoteAddress;
+ int Socket;
+ EFI_STATUS Status;
+ EFI_TPL TplPrevious;
+
+ //
+ // Check for control-C
+ //
+ pRemoteAddress4 = (struct sockaddr_in *)&RemoteAddress;
+ pRemoteAddress6 = (struct sockaddr_in6 *)&RemoteAddress;
+ bListenError = FALSE;
+ Status = ControlCCheck ( );
+ if ( !EFI_ERROR ( Status )) {
+ //
+ // Poll the sockets
+ //
+ FdCount = poll ( &PollFd[0],
+ MaxPort,
+ 0 );
+ if ( -1 == FdCount ) {
+ //
+ // Poll error
+ //
+ DEBUG (( DEBUG_ERROR,
+ "ERROR - Poll error, errno: %d\r\n",
+ errno ));
+ Status = EFI_DEVICE_ERROR;
+ }
+ else {
+ //
+ // Process the poll output
+ //
+ Index = 0;
+ while ( FdCount ) {
+ bRemoveSocket = FALSE;
+
+ //
+ // Account for this descriptor
+ //
+ pPortIpAddress4 = (struct sockaddr_in *)&Port[ Index ].IpAddress;
+ pPortIpAddress6 = (struct sockaddr_in6 *)&Port[ Index ].IpAddress;
+ if ( 0 != PollFd[ Index ].revents ) {
+ FdCount -= 1;
+ }
+
+ //
+ // Check for a broken connection
+ //
+ if ( 0 != ( PollFd[ Index ].revents & POLLHUP )) {
+ bRemoveSocket = TRUE;
+ if ( ListenSocket == PollFd[ Index ].fd ) {
+ bListenError = TRUE;
+ DEBUG (( DEBUG_ERROR,
+ "ERROR - Network closed on listen socket, errno: %d\r\n",
+ errno ));
+ }
+ else {
+ if ( AF_INET == pPortIpAddress4->sin_family ) {
+ DEBUG (( DEBUG_ERROR,
+ "ERROR - Network closed on socket %d.%d.%d.%d:%d, errno: %d\r\n",
+ pPortIpAddress4->sin_addr.s_addr & 0xff,
+ ( pPortIpAddress4->sin_addr.s_addr >> 8 ) & 0xff,
+ ( pPortIpAddress4->sin_addr.s_addr >> 16 ) & 0xff,
+ ( pPortIpAddress4->sin_addr.s_addr >> 24 ) & 0xff,
+ ntohs ( pPortIpAddress4->sin_port ),
+ errno ));
+ }
+ else {
+ DEBUG (( DEBUG_ERROR,
+ "ERROR - Network closed on socket [%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]:%d, errno: %d\r\n",
+ pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 0 ],
+ pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 1 ],
+ pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 2 ],
+ pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 3 ],
+ pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 4 ],
+ pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 5 ],
+ pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 6 ],
+ pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 7 ],
+ pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 8 ],
+ pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 9 ],
+ pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 10 ],
+ pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 11 ],
+ pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 12 ],
+ pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 13 ],
+ pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 14 ],
+ pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 15 ],
+ ntohs ( pPortIpAddress6->sin6_port ),
+ errno ));
+ }
+
+ //
+ // Close the socket
+ //
+ CloseStatus = close ( PollFd[ Index ].fd );
+ if ( 0 == CloseStatus ) {
+ bRemoveSocket = TRUE;
+ if ( AF_INET == pPortIpAddress4->sin_family ) {
+ DEBUG (( DEBUG_INFO,
+ "0x%08x: Socket closed for %d.%d.%d.%d:%d\r\n",
+ PollFd[ Index ].fd,
+ pPortIpAddress4->sin_addr.s_addr & 0xff,
+ ( pPortIpAddress4->sin_addr.s_addr >> 8 ) & 0xff,
+ ( pPortIpAddress4->sin_addr.s_addr >> 16 ) & 0xff,
+ ( pPortIpAddress4->sin_addr.s_addr >> 24 ) & 0xff,
+ ntohs ( pPortIpAddress4->sin_port )));
+ }
+ else {
+ DEBUG (( DEBUG_INFO,
+ "0x%08x: Socket closed for [%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]:%d\r\n",
+ PollFd[ Index ].fd,
+ pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 0 ],
+ pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 1 ],
+ pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 2 ],
+ pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 3 ],
+ pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 4 ],
+ pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 5 ],
+ pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 6 ],
+ pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 7 ],
+ pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 8 ],
+ pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 9 ],
+ pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 10 ],
+ pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 11 ],
+ pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 12 ],
+ pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 13 ],
+ pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 14 ],
+ pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 15 ],
+ ntohs ( pPortIpAddress6->sin6_port )));
+ }
+ }
+ else {
+ if ( AF_INET == pPortIpAddress4->sin_family ) {
+ DEBUG (( DEBUG_ERROR,
+ "ERROR - Failed to close socket 0x%08x for %d.%d.%d.%d:%d, errno: %d\r\n",
+ PollFd[ Index ].fd,
+ pPortIpAddress4->sin_addr.s_addr & 0xff,
+ ( pPortIpAddress4->sin_addr.s_addr >> 8 ) & 0xff,
+ ( pPortIpAddress4->sin_addr.s_addr >> 16 ) & 0xff,
+ ( pPortIpAddress4->sin_addr.s_addr >> 24 ) & 0xff,
+ ntohs ( pPortIpAddress4->sin_port ),
+ errno ));
+ }
+ else {
+ DEBUG (( DEBUG_ERROR,
+ "ERROR - Failed to close socket 0x%08x for [%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]:%d, errno: %d\r\n",
+ PollFd[ Index ].fd,
+ pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 0 ],
+ pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 1 ],
+ pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 2 ],
+ pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 3 ],
+ pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 4 ],
+ pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 5 ],
+ pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 6 ],
+ pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 7 ],
+ pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 8 ],
+ pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 9 ],
+ pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 10 ],
+ pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 11 ],
+ pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 12 ],
+ pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 13 ],
+ pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 14 ],
+ pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 15 ],
+ ntohs ( pPortIpAddress6->sin6_port ),
+ errno ));
+ }
+ }
+ }
+ }
+
+ //
+ // Check for a connection or read data
+ //
+ if ( 0 != ( PollFd[ Index ].revents & POLLRDNORM )) {
+ //
+ // Check for a connection
+ //
+ if ( ListenSocket == PollFd[ Index ].fd ) {
+ //
+ // Another client connection was received
+ //
+ LengthInBytes = sizeof ( RemoteAddress );
+ Socket = accept ( ListenSocket,
+ (struct sockaddr *) &RemoteAddress,
+ &LengthInBytes );
+ if ( -1 == Socket ) {
+ //
+ // Listen socket error
+ //
+ bListenError = TRUE;
+ bRemoveSocket = TRUE;
+ DEBUG (( DEBUG_ERROR,
+ "ERROR - Listen socket failure, errno: %d\r\n",
+ errno ));
+ }
+ else {
+ //
+ // Determine if there is room for this connection
+ //
+ if (( MAX_CONNECTIONS <= MaxPort )
+ || ((( MAX_CONNECTIONS - 1 ) == MaxPort ) && ( -1 == ListenSocket ))) {
+ //
+ // Display the connection
+ //
+ if ( AF_INET == pRemoteAddress4->sin_family ) {
+ Print ( L"Rejecting connection to remote system %d.%d.%d.%d:%d\r\n",
+ pRemoteAddress4->sin_addr.s_addr & 0xff,
+ ( pRemoteAddress4->sin_addr.s_addr >> 8 ) & 0xff,
+ ( pRemoteAddress4->sin_addr.s_addr >> 16 ) & 0xff,
+ ( pRemoteAddress4->sin_addr.s_addr >> 24 ) & 0xff,
+ ntohs ( pRemoteAddress4->sin_port ));
+ }
+ else {
+ Print ( L"Rejecting connection to remote system [%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]:%d\r\n",
+ pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 0 ],
+ pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 1 ],
+ pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 2 ],
+ pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 3 ],
+ pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 4 ],
+ pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 5 ],
+ pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 6 ],
+ pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 7 ],
+ pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 8 ],
+ pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 9 ],
+ pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 10 ],
+ pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 11 ],
+ pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 12 ],
+ pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 13 ],
+ pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 14 ],
+ pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 15 ],
+ ntohs ( pRemoteAddress6->sin6_port ));
+ }
+
+ //
+ // No room for this connection
+ // Close the connection
+ //
+ CloseStatus = close ( Socket );
+ if ( 0 == CloseStatus ) {
+ bRemoveSocket = TRUE;
+ if ( AF_INET == pRemoteAddress4->sin_family ) {
+ DEBUG (( DEBUG_INFO,
+ "0x%08x: Socket closed for %d.%d.%d.%d:%d\r\n",
+ PollFd[ Index ].fd,
+ pRemoteAddress4->sin_addr.s_addr & 0xff,
+ ( pRemoteAddress4->sin_addr.s_addr >> 8 ) & 0xff,
+ ( pRemoteAddress4->sin_addr.s_addr >> 16 ) & 0xff,
+ ( pRemoteAddress4->sin_addr.s_addr >> 24 ) & 0xff,
+ ntohs ( pRemoteAddress4->sin_port )));
+ }
+ else {
+ DEBUG (( DEBUG_INFO,
+ "0x%08x: Socket closed for [%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]:%d\r\n",
+ PollFd[ Index ].fd,
+ pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 0 ],
+ pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 1 ],
+ pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 2 ],
+ pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 3 ],
+ pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 4 ],
+ pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 5 ],
+ pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 6 ],
+ pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 7 ],
+ pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 8 ],
+ pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 9 ],
+ pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 10 ],
+ pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 11 ],
+ pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 12 ],
+ pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 13 ],
+ pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 14 ],
+ pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 15 ],
+ ntohs ( pRemoteAddress6->sin6_port )));
+ }
+ }
+ else {
+ DEBUG (( DEBUG_ERROR,
+ "ERROR - Failed to close socket 0x%08x, errno: %d\r\n",
+ PollFd[ Index ].fd,
+ errno ));
+ }
+
+ //
+ // Keep the application running
+ // No issue with the listen socket
+ //
+ Status = EFI_SUCCESS;
+ }
+ else {
+ //
+ // Display the connection
+ //
+ if ( AF_INET == pRemoteAddress4->sin_family ) {
+ Print ( L"Connected to remote system %d.%d.%d.%d:%d\r\n",
+ pRemoteAddress4->sin_addr.s_addr & 0xff,
+ ( pRemoteAddress4->sin_addr.s_addr >> 8 ) & 0xff,
+ ( pRemoteAddress4->sin_addr.s_addr >> 16 ) & 0xff,
+ ( pRemoteAddress4->sin_addr.s_addr >> 24 ) & 0xff,
+ ntohs ( pRemoteAddress4->sin_port ));
+ }
+ else {
+ Print ( L"Connected to remote system [%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]:%d\r\n",
+ pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 0 ],
+ pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 1 ],
+ pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 2 ],
+ pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 3 ],
+ pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 4 ],
+ pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 5 ],
+ pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 6 ],
+ pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 7 ],
+ pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 8 ],
+ pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 9 ],
+ pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 10 ],
+ pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 11 ],
+ pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 12 ],
+ pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 13 ],
+ pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 14 ],
+ pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 15 ],
+ ntohs ( pRemoteAddress6->sin6_port ));
+ }
+
+ //
+ // Allocate the client connection
+ //
+ Index = MaxPort++;
+ ZeroMem ( &Port[ Index ], sizeof ( Port[ Index ]));
+ CopyMem ( pPortIpAddress6, pRemoteAddress6, sizeof ( *pRemoteAddress6 ));
+ PollFd[ Index ].fd = Socket;
+ PollFd[ Index ].events = POLLRDNORM | POLLHUP;
+ PollFd[ Index ].revents = 0;
+ }
+ }
+ }
+ else {
+ //
+ // Data received
+ //
+ BytesReceived = read ( PollFd[ Index ].fd,
+ &Buffer,
+ sizeof ( Buffer ));
+ if ( 0 < BytesReceived ) {
+ //
+ // Display the amount of data received
+ //
+ if ( AF_INET == pPortIpAddress4->sin_family ) {
+ DEBUG (( DEBUG_INFO,
+ "0x%08x: Socket received 0x%08x bytes from %d.%d.%d.%d:%d\r\n",
+ PollFd[ Index ].fd,
+ BytesReceived,
+ pPortIpAddress4->sin_addr.s_addr & 0xff,
+ ( pPortIpAddress4->sin_addr.s_addr >> 8 ) & 0xff,
+ ( pPortIpAddress4->sin_addr.s_addr >> 16 ) & 0xff,
+ ( pPortIpAddress4->sin_addr.s_addr >> 24 ) & 0xff,
+ ntohs ( pPortIpAddress4->sin_port )));
+ }
+ else {
+ DEBUG (( DEBUG_INFO,
+ "0x%08x: Socket received 0x%08x bytes from [%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]:%d\r\n",
+ PollFd[ Index ].fd,
+ BytesReceived,
+ pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 0 ],
+ pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 1 ],
+ pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 2 ],
+ pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 3 ],
+ pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 4 ],
+ pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 5 ],
+ pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 6 ],
+ pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 7 ],
+ pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 8 ],
+ pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 9 ],
+ pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 10 ],
+ pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 11 ],
+ pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 12 ],
+ pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 13 ],
+ pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 14 ],
+ pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 15 ],
+ ntohs ( pPortIpAddress6->sin6_port )));
+ }
+
+ //
+ // Synchronize with the TimerCallback routine
+ //
+ TplPrevious = gBS->RaiseTPL ( TPL_DATASINK );
+
+ //
+ // Account for the data received
+ //
+ Port[ Index ].BytesTotal += BytesReceived;
+
+ //
+ // Release the synchronization with the TimerCallback routine
+ //
+ gBS->RestoreTPL ( TplPrevious );
+ }
+ else if ( -1 == BytesReceived ) {
+ //
+ // Close the socket
+ //
+ if ( AF_INET == pPortIpAddress4->sin_family ) {
+ DEBUG (( DEBUG_INFO,
+ "ERROR - Receive failure for %d.%d.%d.%d:%d, errno: %d\r\n",
+ pPortIpAddress4->sin_addr.s_addr & 0xff,
+ ( pPortIpAddress4->sin_addr.s_addr >> 8 ) & 0xff,
+ ( pPortIpAddress4->sin_addr.s_addr >> 16 ) & 0xff,
+ ( pPortIpAddress4->sin_addr.s_addr >> 24 ) & 0xff,
+ ntohs ( pPortIpAddress4->sin_port ),
+ errno ));
+ }
+ else {
+ DEBUG (( DEBUG_INFO,
+ "ERROR - Receive failure for [%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]:%d, errno: %d\r\n",
+ pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 0 ],
+ pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 1 ],
+ pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 2 ],
+ pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 3 ],
+ pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 4 ],
+ pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 5 ],
+ pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 6 ],
+ pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 7 ],
+ pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 8 ],
+ pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 9 ],
+ pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 10 ],
+ pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 11 ],
+ pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 12 ],
+ pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 13 ],
+ pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 14 ],
+ pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 15 ],
+ ntohs ( pPortIpAddress6->sin6_port ),
+ errno ));
+ }
+ CloseStatus = close ( PollFd[ Index ].fd );
+ if ( 0 == CloseStatus ) {
+ bRemoveSocket = TRUE;
+ if ( AF_INET == pPortIpAddress4->sin_family ) {
+ DEBUG (( DEBUG_INFO,
+ "0x%08x: Socket closed for %d.%d.%d.%d:%d\r\n",
+ PollFd[ Index ].fd,
+ pPortIpAddress4->sin_addr.s_addr & 0xff,
+ ( pPortIpAddress4->sin_addr.s_addr >> 8 ) & 0xff,
+ ( pPortIpAddress4->sin_addr.s_addr >> 16 ) & 0xff,
+ ( pPortIpAddress4->sin_addr.s_addr >> 24 ) & 0xff,
+ ntohs ( pPortIpAddress4->sin_port )));
+ }
+ else {
+ DEBUG (( DEBUG_INFO,
+ "0x%08x: Socket closed for [%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]:%d\r\n",
+ PollFd[ Index ].fd,
+ pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 0 ],
+ pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 1 ],
+ pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 2 ],
+ pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 3 ],
+ pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 4 ],
+ pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 5 ],
+ pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 6 ],
+ pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 7 ],
+ pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 8 ],
+ pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 9 ],
+ pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 10 ],
+ pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 11 ],
+ pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 12 ],
+ pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 13 ],
+ pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 14 ],
+ pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 15 ],
+ ntohs ( pPortIpAddress6->sin6_port )));
+ }
+ }
+ else {
+ if ( AF_INET == pPortIpAddress4->sin_family ) {
+ DEBUG (( DEBUG_ERROR,
+ "ERROR - Failed to close socket 0x%08x for %d.%d.%d.%d:%d, errno: %d\r\n",
+ PollFd[ Index ].fd,
+ pPortIpAddress4->sin_addr.s_addr & 0xff,
+ ( pPortIpAddress4->sin_addr.s_addr >> 8 ) & 0xff,
+ ( pPortIpAddress4->sin_addr.s_addr >> 16 ) & 0xff,
+ ( pPortIpAddress4->sin_addr.s_addr >> 24 ) & 0xff,
+ ntohs ( pPortIpAddress4->sin_port ),
+ errno ));
+ }
+ else {
+ DEBUG (( DEBUG_ERROR,
+ "ERROR - Failed to close socket 0x%08x for [%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]:%d, errno: %d\r\n",
+ PollFd[ Index ].fd,
+ pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 0 ],
+ pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 1 ],
+ pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 2 ],
+ pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 3 ],
+ pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 4 ],
+ pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 5 ],
+ pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 6 ],
+ pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 7 ],
+ pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 8 ],
+ pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 9 ],
+ pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 10 ],
+ pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 11 ],
+ pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 12 ],
+ pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 13 ],
+ pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 14 ],
+ pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 15 ],
+ ntohs ( pPortIpAddress6->sin6_port ),
+ errno ));
+ }
+ }
+ }
+
+ //
+ // Keep the application running
+ // No issue with the listen socket
+ //
+ Status = EFI_SUCCESS;
+ }
+ }
+
+ //
+ // Remove the socket if necessary
+ //
+ if ( bRemoveSocket ) {
+ DEBUG (( DEBUG_INFO,
+ "0x%08x: Socket removed from polling\r\n",
+ PollFd[ Index ].fd ));
+ MaxPort -= 1;
+ for ( Entry = Index + 1; MaxPort >= Entry; Entry++ ) {
+ EntryPrevious = Entry;
+ CopyMem ( &Port[ EntryPrevious ],
+ &Port[ Entry ],
+ sizeof ( Port[ Entry ]));
+ PollFd[ EntryPrevious ].events = PollFd[ Entry ].events;
+ PollFd[ EntryPrevious ].fd = PollFd[ Entry ].fd;
+ PollFd[ EntryPrevious ].revents = PollFd[ Entry ].revents;
+ }
+ PollFd[ MaxPort ].fd = -1;
+ Index -= 1;
+ }
+
+ //
+ // Account for this socket
+ //
+ Index += 1;
+ }
+ }
+ }
+
+ //
+ // Return the listen failure if necessary
+ //
+ if (( !EFI_ERROR ( Status )) && bListenError ) {
+ Status = EFI_NOT_STARTED;
+ }
+
+ //
+ // Return the poll status
+ //
+ return Status;
+}
+
+
+/**
+ Handle the timer callback
+
+ @param [in] Event Event that caused this callback
+ @param [in] pContext Context for this routine
+**/
+VOID
+EFIAPI
+TimerCallback (
+ IN EFI_EVENT Event,
+ IN VOID * pContext
+ )
+{
+ UINT32 Average;
+ UINT64 BitsPerSecond;
+ UINT64 BytesReceived;
+ UINT32 Count;
+ nfds_t Index;
+ UINT64 TotalBytes;
+
+ //
+ // Notify the other code of the timer tick
+ //
+ bTick = TRUE;
+
+ //
+ // Walk the list of ports
+ //
+ for ( Index = 0; MaxPort > Index; Index++ ) {
+ //
+ // Determine if any data was received
+ //
+ BytesReceived = Port[ Index ].BytesTotal;
+ if (( ListenSocket != PollFd[ Index ].fd )
+ && ( 0 != BytesReceived )) {
+ //
+ // Update the received data samples
+ //
+ Port[ Index ].BytesTotal = 0;
+ Port[ Index ].BytesReceived [ Port[ Index ].In ] = BytesReceived;
+ Port[ Index ].In += 1;
+ if ( DATA_SAMPLES <= Port[ Index ].In ) {
+ Port[ Index ].In = 0;
+ }
+
+ //
+ // Separate the samples
+ //
+ if ( DATA_SAMPLES == Port[ Index ].Samples ) {
+ Print ( L"---------- Stable average ----------\r\n" );
+ }
+ Port[ Index ].Samples += 1;
+
+ //
+ // Compute the data rate
+ //
+ TotalBytes = 0;
+ for ( Count = 0; DATA_SAMPLES > Count; Count++ )
+ {
+ TotalBytes += Port[ Index ].BytesReceived[ Count ];
+ }
+ Average = (UINT32)RShiftU64 ( TotalBytes, DATA_SAMPLE_SHIFT );
+ BitsPerSecond = Average * 8;
+
+ //
+ // Display the data rate
+ //
+ if (( RANGE_SWITCH >> 10 ) > Average ) {
+ Print ( L"Ave: %d Bytes/Sec, %Ld Bits/sec\r\n",
+ Average,
+ BitsPerSecond );
+ }
+ else {
+ BitsPerSecond /= 1000;
+ if ( RANGE_SWITCH > Average ) {
+ Print ( L"Ave: %d.%03d KiBytes/Sec, %Ld KBits/sec\r\n",
+ Average >> 10,
+ (( Average & 0x3ff ) * 1000 ) >> 10,
+ BitsPerSecond );
+ }
+ else {
+ BitsPerSecond /= 1000;
+ Average >>= 10;
+ if ( RANGE_SWITCH > Average ) {
+ Print ( L"Ave: %d.%03d MiBytes/Sec, %Ld MBits/sec\r\n",
+ Average >> 10,
+ (( Average & 0x3ff ) * 1000 ) >> 10,
+ BitsPerSecond );
+ }
+ else {
+ BitsPerSecond /= 1000;
+ Average >>= 10;
+ if ( RANGE_SWITCH > Average ) {
+ Print ( L"Ave: %d.%03d GiBytes/Sec, %Ld GBits/sec\r\n",
+ Average >> 10,
+ (( Average & 0x3ff ) * 1000 ) >> 10,
+ BitsPerSecond );
+ }
+ else {
+ BitsPerSecond /= 1000;
+ Average >>= 10;
+ if ( RANGE_SWITCH > Average ) {
+ Print ( L"Ave: %d.%03d TiBytes/Sec, %Ld TBits/sec\r\n",
+ Average >> 10,
+ (( Average & 0x3ff ) * 1000 ) >> 10,
+ BitsPerSecond );
+ }
+ else {
+ BitsPerSecond /= 1000;
+ Average >>= 10;
+ Print ( L"Ave: %d.%03d PiBytes/Sec, %Ld PBits/sec\r\n",
+ Average >> 10,
+ (( Average & 0x3ff ) * 1000 ) >> 10,
+ BitsPerSecond );
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+
+/**
+ Create the timer
+
+ @retval EFI_SUCCESS The timer was successfully created
+ @retval Other Timer initialization failed
+**/
+EFI_STATUS
+TimerCreate (
+ )
+{
+ EFI_STATUS Status;
+
+ //
+ // Create the timer
+ //
+ Status = gBS->CreateEvent ( EVT_TIMER | EVT_NOTIFY_SIGNAL,
+ TPL_DATASINK,
+ TimerCallback,
+ NULL,
+ &pTimer );
+ if ( EFI_ERROR ( Status )) {
+ DEBUG (( DEBUG_ERROR,
+ "ERROR - Failed to allocate the timer event, Status: %r\r\n",
+ Status ));
+ }
+ else {
+ DEBUG (( DEBUG_INFO,
+ "0x%08x: Timer created\r\n",
+ pTimer ));
+ }
+
+ //
+ // Return the operation status
+ //
+ return Status;
+}
+
+
+/**
+ Stop the timer
+
+ @retval EFI_SUCCESS The timer was stopped successfully
+ @retval Other The timer failed to stop
+**/
+EFI_STATUS
+TimerStop (
+ )
+{
+ EFI_STATUS Status;
+
+ //
+ // Assume success
+ //
+ Status = EFI_SUCCESS;
+
+ //
+ // Determine if the timer is running
+ //
+ if ( bTimerRunning ) {
+ //
+ // Stop the timer
+ //
+ Status = gBS->SetTimer ( pTimer,
+ TimerCancel,
+ 0 );
+ if ( EFI_ERROR ( Status )) {
+ DEBUG (( DEBUG_ERROR,
+ "ERROR - Failed to stop the timer, Status: %r\r\n",
+ Status ));
+ }
+ else {
+ //
+ // Timer timer is now stopped
+ //
+ bTimerRunning = FALSE;
+ DEBUG (( DEBUG_INFO,
+ "0x%08x: Timer stopped\r\n",
+ pTimer ));
+ }
+ }
+
+ //
+ // Return the operation status
+ //
+ return Status;
+}
+
+
+/**
+ Start the timer
+
+ @param [in] Milliseconds The number of milliseconds between timer callbacks
+
+ @retval EFI_SUCCESS The timer was successfully created
+ @retval Other Timer initialization failed
+**/
+EFI_STATUS
+TimerStart (
+ UINTN Milliseconds
+ )
+{
+ EFI_STATUS Status;
+ UINT64 TimeDelay;
+
+ //
+ // Stop the timer if necessary
+ //
+ Status = EFI_SUCCESS;
+ if ( bTimerRunning ) {
+ Status = TimerStop ( );
+ }
+ if ( !EFI_ERROR ( Status )) {
+ //
+ // Compute the new delay
+ //
+ TimeDelay = Milliseconds;
+ TimeDelay *= 1000 * 10;
+
+ //
+ // Start the timer
+ //
+ Status = gBS->SetTimer ( pTimer,
+ TimerPeriodic,
+ TimeDelay );
+ if ( EFI_ERROR ( Status )) {
+ DEBUG (( DEBUG_ERROR,
+ "ERROR - Failed to start the timer, Status: %r\r\n",
+ Status ));
+ }
+ else {
+ //
+ // The timer is now running
+ //
+ bTimerRunning = TRUE;
+ DEBUG (( DEBUG_INFO,
+ "0x%08x: Timer running\r\n",
+ pTimer ));
+ }
+ }
+
+ //
+ // Return the operation status
+ //
+ return Status;
+}
+
+
+/**
+ Destroy the timer
+
+ @retval EFI_SUCCESS The timer was destroyed successfully
+ @retval Other Failed to destroy the timer
+**/
+EFI_STATUS
+TimerDestroy (
+ )
+{
+ EFI_STATUS Status;
+
+ //
+ // Assume success
+ //
+ Status = EFI_SUCCESS;
+
+ //
+ // Determine if the timer is running
+ //
+ if ( bTimerRunning ) {
+ //
+ // Stop the timer
+ //
+ Status = TimerStop ( );
+ }
+ if (( !EFI_ERROR ( Status )) && ( NULL != pTimer )) {
+ //
+ // Done with this timer
+ //
+ Status = gBS->CloseEvent ( pTimer );
+ if ( EFI_ERROR ( Status )) {
+ DEBUG (( DEBUG_ERROR,
+ "ERROR - Failed to free the timer event, Status: %r\r\n",
+ Status ));
+ }
+ else {
+ DEBUG (( DEBUG_INFO,
+ "0x%08x: Timer Destroyed\r\n",
+ pTimer ));
+ pTimer = NULL;
+ }
+ }
+
+ //
+ // Return the operation status
+ //
+ return Status;
+}
+
+
+/**
+ Receive data from the DataSource program to test a network's bandwidth.
+
+ @param [in] Argc The number of arguments
+ @param [in] Argv The argument value array
+
+ @retval 0 The application exited normally.
+ @retval Other An error occurred.
+**/
+int
+main (
+ IN int Argc,
+ IN char **Argv
+ )
+{
+ sa_family_t Family;
+ EFI_STATUS Status;
+
+ DEBUG (( DEBUG_INFO,
+ "DataSink starting\r\n" ));
+
+ //
+ // Determine the family to use
+ //
+ Family = ( 1 < Argc ) ? AF_INET6 : AF_INET;
+
+ //
+ // Use for/break instead of goto
+ //
+ for ( ; ; ) {
+ //
+ // Create the timer
+ //
+ bTick = TRUE;
+ Status = TimerCreate ( );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Start a timer to perform network polling and display updates
+ //
+ Status = TimerStart ( 1 * 1000 );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Loop forever waiting for abuse
+ //
+ do {
+ ListenSocket = -1;
+ do {
+ //
+ // Complete any client operations
+ //
+ Status = SocketPoll ( );
+ if ( EFI_ERROR ( Status )) {
+ //
+ // Control-C
+ //
+ break;
+ }
+
+ //
+ // Wait for a while
+ //
+ } while ( !bTick );
+ if ( EFI_ERROR ( Status )) {
+ //
+ // Control-C
+ //
+ break;
+ }
+
+ //
+ // Wait for the network layer to initialize
+ //
+ Status = SocketNew ( Family );
+ if ( EFI_ERROR ( Status )) {
+ continue;
+ }
+
+ //
+ // Wait for the remote network application to start
+ //
+ Status = SocketAccept ( );
+ if ( EFI_NOT_STARTED == Status ) {
+ Status = SocketClose ( );
+ continue;
+ }
+ else if ( EFI_SUCCESS != Status ) {
+ //
+ // Control-C
+ //
+ break;
+ }
+
+ //
+ // Receive data until the connection breaks
+ //
+ do {
+ Status = SocketPoll ( );
+ } while ( !EFI_ERROR ( Status ));
+
+ //
+ // Done with the socket
+ //
+ Status = SocketClose ( );
+ } while ( !EFI_ERROR ( Status ));
+
+ //
+ // Close the socket if necessary
+ //
+ SocketClose ( );
+
+ //
+ // All done
+ //
+ break;
+ }
+
+ //
+ // Stop the timer if necessary
+ //
+ TimerStop ( );
+ TimerDestroy ( );
+
+ //
+ // Return the operation status
+ //
+ DEBUG (( DEBUG_INFO,
+ "DataSink exiting, Status: %r\r\n",
+ Status ));
+ return Status;
+}
diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/DataSink/DataSink.inf b/uefi/linaro-edk2/AppPkg/Applications/Sockets/DataSink/DataSink.inf
new file mode 100644
index 0000000..9ad6fd9
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/DataSink/DataSink.inf
@@ -0,0 +1,61 @@
+## @file
+# DataSink Application
+#
+# Copyright (c) 2011-2012, Intel Corporation
+# All rights reserved. This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = DataSink
+ FILE_GUID = A85DCA1B-198F-4e14-A673-874264687E85
+ MODULE_TYPE = UEFI_APPLICATION
+ VERSION_STRING = 1.0
+ ENTRY_POINT = ShellCEntryLib
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF EBC
+#
+
+[Sources]
+ DataSink.c
+
+
+[Pcd]
+ gAppPkgTokenSpaceGuid.DataSource_Port
+
+
+[Packages]
+ AppPkg/AppPkg.dec
+ MdePkg/MdePkg.dec
+ ShellPkg/ShellPkg.dec
+ StdLib/StdLib.dec
+
+
+[LibraryClasses]
+ BaseMemoryLib
+ BsdSocketLib
+ DebugLib
+ EfiSocketLib
+ LibC
+ LibMath
+ ShellCEntryLib
+ UefiBootServicesTableLib
+ UefiLib
+# UseSocketDxe
+
+[BuildOptions]
+ INTEL:*_*_*_CC_FLAGS = /Qdiag-disable:181,186
+ MSFT:*_*_*_CC_FLAGS = /Od
+ GCC:*_*_*_CC_FLAGS = -O0 -Wno-unused-variable
+
diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/DataSource/DataSource.c b/uefi/linaro-edk2/AppPkg/Applications/Sockets/DataSource/DataSource.c
new file mode 100644
index 0000000..0dcd882
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/DataSource/DataSource.c
@@ -0,0 +1,1755 @@
+/** @file
+ Data source for network testing.
+
+ Copyright (c) 2011-2012, Intel Corporation
+ All rights reserved. This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <errno.h>
+#include <Uefi.h>
+
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/PcdLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiLib.h>
+
+#include <netinet/in.h>
+
+#include <Protocol/ServiceBinding.h>
+#include <Protocol/Tcp4.h>
+
+#include <sys/EfiSysCall.h>
+#include <sys/poll.h>
+#include <sys/socket.h>
+
+#include <stdio.h>
+#include <string.h>
+
+
+#define DATA_SAMPLE_SHIFT 5 ///< Shift for number of samples
+#define RANGE_SWITCH ( 1024 * 1024 ) ///< Switch display ranges
+#define DATA_RATE_UPDATE_SHIFT 2 ///< 2n seconds between updates
+#define AVERAGE_SHIFT_COUNT ( 6 - DATA_RATE_UPDATE_SHIFT ) ///< 2n samples in average
+#define DATA_SAMPLES ( 1 << DATA_SAMPLE_SHIFT ) ///< Number of samples
+
+#define TPL_DATASOURCE TPL_CALLBACK ///< Synchronization TPL
+
+#define PACKET_SIZE 1448 ///< Size of data packets
+#define DATA_BUFFER_SIZE (( 65536 / PACKET_SIZE ) * PACKET_SIZE ) ///< Buffer size in bytes
+
+
+//
+// Socket Data
+//
+int Socket = -1;
+
+//
+// TCP V4 Data
+//
+BOOLEAN bTcp4; ///< TRUE if TCP4 is being used
+BOOLEAN bTcp4Connected; ///< TRUE if connected to remote system
+BOOLEAN bTcp4Connecting; ///< TRUE while connection in progress
+UINTN Tcp4Index; ///< Index into handle array
+EFI_HANDLE Tcp4Controller; ///< Network controller handle
+EFI_HANDLE Tcp4Handle; ///< TCP4 port handle
+EFI_TCP4_PROTOCOL * pTcp4Protocol; ///< TCP4 protocol pointer
+EFI_SERVICE_BINDING_PROTOCOL * pTcp4Service; ///< TCP4 Service binding
+EFI_TCP4_CONFIG_DATA Tcp4ConfigData;///< TCP4 configuration data
+EFI_TCP4_OPTION Tcp4Option; ///< TCP4 port options
+EFI_TCP4_CLOSE_TOKEN Tcp4CloseToken;///< Close control
+EFI_TCP4_CONNECTION_TOKEN Tcp4ConnectToken; ///< Connection control
+EFI_TCP4_LISTEN_TOKEN Tcp4ListenToken; ///< Listen control
+EFI_TCP4_IO_TOKEN Tcp4TxToken; ///< Normal data token
+
+//
+// Timer Data
+//
+volatile BOOLEAN bTick;
+BOOLEAN bTimerRunning;
+EFI_EVENT pTimer;
+
+//
+// Remote IP Address Data
+//
+struct sockaddr_in6 RemoteHostAddress;
+CHAR8 * pRemoteHost;
+
+//
+// Traffic Data
+//
+UINT64 TotalBytesSent;
+UINT32 In;
+UINT32 Samples;
+UINT64 BytesSent[ DATA_SAMPLES ];
+UINT8 Buffer[ DATA_BUFFER_SIZE ];
+
+
+//
+// Forward routine declarations
+//
+EFI_STATUS TimerStart ( UINTN Milliseconds );
+
+
+/**
+ Check for control C entered at console
+
+ @retval EFI_SUCCESS Control C not entered
+ @retval EFI_ABORTED Control C entered
+**/
+EFI_STATUS
+ControlCCheck (
+ )
+{
+ EFI_STATUS Status;
+
+ //
+ // Assume no user intervention
+ //
+ Status = EFI_SUCCESS;
+
+ //
+ // Display user stop request
+ //
+ if ( EFI_ERROR ( Status )) {
+ DEBUG (( DEBUG_INFO,
+ "User stop request!\r\n" ));
+ }
+
+ //
+ // Return the check status
+ //
+ return Status;
+}
+
+
+/**
+ Get a digit
+
+ @param [in] pDigit The address of the next digit
+ @param [out] pValue The address to receive the value
+
+ @return Returns the address of the separator
+
+**/
+CHAR8 *
+GetDigit (
+ CHAR8 * pDigit,
+ UINT32 * pValue
+ )
+{
+ UINT32 Value;
+
+ //
+ // Walk the digits
+ //
+ Value = 0;
+ while (( '0' <= *pDigit ) && ( '9' >= *pDigit )) {
+ //
+ // Make room for the new least significant digit
+ //
+ Value *= 10;
+
+ //
+ // Convert the digit from ASCII to binary
+ //
+ Value += *pDigit - '0';
+
+ //
+ // Set the next digit
+ //
+ pDigit += 1;
+ }
+
+ //
+ // Return the value
+ //
+ *pValue = Value;
+
+ //
+ // Return the next separator
+ //
+ return pDigit;
+}
+
+
+/**
+ Get the IP address
+
+ @retval EFI_SUCCESS The IP address is valid
+ @retval Other Failure to convert the IP address
+**/
+EFI_STATUS
+IpAddress (
+ )
+{
+ struct sockaddr_in * pRemoteAddress4;
+ struct sockaddr_in6 * pRemoteAddress6;
+ UINT32 RemoteAddress;
+ EFI_STATUS Status;
+ UINT32 Value1;
+ UINT32 Value2;
+ UINT32 Value3;
+ UINT32 Value4;
+ UINT32 Value5;
+ UINT32 Value6;
+ UINT32 Value7;
+ UINT32 Value8;
+
+ //
+ // Assume failure
+ //
+ Status = EFI_INVALID_PARAMETER;
+
+ //
+ // Get the port number
+ //
+ ZeroMem ( &RemoteHostAddress, sizeof ( RemoteHostAddress ));
+ RemoteHostAddress.sin6_port = htons ( PcdGet16 ( DataSource_Port ));
+ pRemoteAddress4 = (struct sockaddr_in *)&RemoteHostAddress;
+ pRemoteAddress6 = &RemoteHostAddress;
+
+ //
+ // Convert the IP address from a string to a numeric value
+ //
+ if (( 4 == sscanf ( pRemoteHost,
+ "%d.%d.%d.%d",
+ &Value1,
+ &Value2,
+ &Value3,
+ &Value4 ))
+ && ( 255 >= Value1 )
+ && ( 255 >= Value2 )
+ && ( 255 >= Value3 )
+ && ( 255 >= Value4 )) {
+ //
+ // Build the IPv4 address
+ //
+ pRemoteAddress4->sin_len = sizeof ( *pRemoteAddress4 );
+ pRemoteAddress4->sin_family = AF_INET;
+ RemoteAddress = Value1
+ | ( Value2 << 8 )
+ | ( Value3 << 16 )
+ | ( Value4 << 24 );
+ pRemoteAddress4->sin_addr.s_addr = RemoteAddress;
+ Status = EFI_SUCCESS;
+
+ //
+ // Display the IP address
+ //
+ DEBUG (( DEBUG_INFO,
+ "%d.%d.%d.%d: Remote host IP address\r\n",
+ Value1,
+ Value2,
+ Value3,
+ Value4 ));
+ }
+ else if (( 8 == sscanf ( pRemoteHost,
+ "%x:%x:%x:%x:%x:%x:%x:%x",
+ &Value1,
+ &Value2,
+ &Value3,
+ &Value4,
+ &Value5,
+ &Value6,
+ &Value7,
+ &Value8 ))
+ && ( 0xffff >= Value1 )
+ && ( 0xffff >= Value2 )
+ && ( 0xffff >= Value3 )
+ && ( 0xffff >= Value4 )
+ && ( 0xffff >= Value5 )
+ && ( 0xffff >= Value6 )
+ && ( 0xffff >= Value7 )
+ && ( 0xffff >= Value8 )) {
+ //
+ // Build the IPv6 address
+ //
+ pRemoteAddress6->sin6_len = sizeof ( *pRemoteAddress6 );
+ pRemoteAddress6->sin6_family = AF_INET6;
+ pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 0 ] = (UINT8)( Value1 >> 8 );
+ pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 1 ] = (UINT8)Value1;
+ pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 2 ] = (UINT8)( Value2 >> 8 );
+ pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 3 ] = (UINT8)Value2;
+ pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 4 ] = (UINT8)( Value3 >> 8 );
+ pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 5 ] = (UINT8)Value3;
+ pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 6 ] = (UINT8)( Value4 >> 8 );
+ pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 7 ] = (UINT8)Value4;
+ pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 8 ] = (UINT8)( Value5 >> 8 );
+ pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 9 ] = (UINT8)Value5;
+ pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 10 ] = (UINT8)( Value6 >> 8 );
+ pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 11 ] = (UINT8)Value6;
+ pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 12 ] = (UINT8)( Value7 >> 8 );
+ pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 13 ] = (UINT8)Value7;
+ pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 14 ] = (UINT8)( Value8 >> 8 );
+ pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 15 ] = (UINT8)Value8;
+ Status = EFI_SUCCESS;
+
+ //
+ // Display the IP address
+ //
+ DEBUG (( DEBUG_INFO,
+ "[%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x]: Remote host IP address\r\n",
+ Value1,
+ Value2,
+ Value3,
+ Value4,
+ Value5,
+ Value6,
+ Value7,
+ Value8 ));
+ }
+ else {
+ Print ( L"ERROR - Invalid IP address!\r\n" );
+ }
+
+ //
+ // Return the operation status
+ //
+ return Status;
+}
+
+
+/**
+ Close the socket
+
+ @retval EFI_SUCCESS The application is running normally
+ @retval Other The user stopped the application
+**/
+EFI_STATUS
+SocketClose (
+ )
+{
+ int CloseStatus;
+ EFI_STATUS Status;
+
+ //
+ // Determine if the socket is open
+ //
+ Status = EFI_DEVICE_ERROR;
+ if ( -1 != Socket ) {
+ //
+ // Attempt to close the socket
+ //
+ CloseStatus = close ( Socket );
+ if ( 0 == CloseStatus ) {
+ DEBUG (( DEBUG_INFO,
+ "0x%08x: Socket closed\r\n",
+ Socket ));
+ Socket = -1;
+ Status = EFI_SUCCESS;
+ }
+ else {
+ DEBUG (( DEBUG_ERROR,
+ "ERROR: Failed to close socket, errno: %d\r\n",
+ errno ));
+ }
+ }
+
+ //
+ // Return the operation status
+ //
+ return Status;
+}
+
+
+/**
+ Connect the socket
+
+ @retval EFI_SUCCESS The application is running normally
+ @retval Other The user stopped the application
+**/
+EFI_STATUS
+SocketConnect (
+ )
+{
+ int ConnectStatus;
+ struct sockaddr_in * pRemoteAddress4;
+ struct sockaddr_in6 * pRemoteAddress6;
+ EFI_STATUS Status;
+
+ //
+ // Display the connecting message
+ //
+ pRemoteAddress4 = (struct sockaddr_in *)&RemoteHostAddress;
+ pRemoteAddress6 = &RemoteHostAddress;
+ if ( AF_INET == pRemoteAddress6->sin6_family ) {
+ Print ( L"Connecting to remote system %d.%d.%d.%d:%d\r\n",
+ pRemoteAddress4->sin_addr.s_addr & 0xff,
+ ( pRemoteAddress4->sin_addr.s_addr >> 8 ) & 0xff,
+ ( pRemoteAddress4->sin_addr.s_addr >> 16 ) & 0xff,
+ ( pRemoteAddress4->sin_addr.s_addr >> 24 ) & 0xff,
+ ntohs ( pRemoteAddress4->sin_port ));
+ }
+ else {
+ Print ( L"Connecting to remote system [%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]:%d\r\n",
+ pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 0 ],
+ pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 1 ],
+ pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 2 ],
+ pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 3 ],
+ pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 4 ],
+ pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 5 ],
+ pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 6 ],
+ pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 7 ],
+ pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 8 ],
+ pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 9 ],
+ pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 10 ],
+ pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 11 ],
+ pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 12 ],
+ pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 13 ],
+ pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 14 ],
+ pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 15 ],
+ ntohs ( pRemoteAddress6->sin6_port ));
+ }
+
+ //
+ // Connect to the remote system
+ //
+ Status = EFI_SUCCESS;
+ do {
+ //
+ // Check for user stop request
+ //
+ while ( !bTick ) {
+ Status = ControlCCheck ( );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ }
+ bTick = FALSE;
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Connect to the remote system
+ //
+ ConnectStatus = connect ( Socket,
+ (struct sockaddr *)pRemoteAddress6,
+ pRemoteAddress6->sin6_len );
+ if ( -1 != ConnectStatus ) {
+ if ( AF_INET == pRemoteAddress6->sin6_family ) {
+ Print ( L"Connected to remote system %d.%d.%d.%d:%d\r\n",
+ pRemoteAddress4->sin_addr.s_addr & 0xff,
+ ( pRemoteAddress4->sin_addr.s_addr >> 8 ) & 0xff,
+ ( pRemoteAddress4->sin_addr.s_addr >> 16 ) & 0xff,
+ ( pRemoteAddress4->sin_addr.s_addr >> 24 ) & 0xff,
+ ntohs ( pRemoteAddress4->sin_port ));
+ }
+ else {
+ Print ( L"Connected to remote system [%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]:%d\r\n",
+ pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 0 ],
+ pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 1 ],
+ pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 2 ],
+ pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 3 ],
+ pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 4 ],
+ pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 5 ],
+ pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 6 ],
+ pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 7 ],
+ pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 8 ],
+ pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 9 ],
+ pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 10 ],
+ pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 11 ],
+ pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 12 ],
+ pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 13 ],
+ pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 14 ],
+ pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 15 ],
+ ntohs ( pRemoteAddress6->sin6_port ));
+ }
+Print ( L"ConnectStatus: %d, Status: %r\r\n", ConnectStatus, Status );
+ }
+ else {
+ //
+ // Close the socket and try again
+ //
+ if ( EAGAIN != errno ) {
+ Status = EFI_NOT_STARTED;
+ break;
+ }
+ }
+ } while ( -1 == ConnectStatus );
+
+ //
+ // Return the operation status
+ //
+Print ( L"SocketConnect returning Status: %r\r\n", Status );
+ return Status;
+}
+
+
+/**
+ Create the socket
+
+ @param [in] Family Network family, AF_INET or AF_INET6
+
+ @retval EFI_SUCCESS The application is running normally
+ @retval Other The user stopped the application
+**/
+EFI_STATUS
+SocketNew (
+ sa_family_t Family
+ )
+{
+ EFI_STATUS Status;
+
+ //
+ // Loop creating the socket
+ //
+ DEBUG (( DEBUG_INFO,
+ "Creating the socket\r\n" ));
+ do {
+ //
+ // Check for user stop request
+ //
+ Status = ControlCCheck ( );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Attempt to create the socket
+ //
+ Socket = socket ( Family,
+ SOCK_STREAM,
+ IPPROTO_TCP );
+ if ( -1 != Socket ) {
+ DEBUG (( DEBUG_INFO,
+ "0x%08x: Socket created\r\n",
+ Socket ));
+ break;
+ }
+ } while ( -1 == Socket );
+
+ //
+ // Return the operation status
+ //
+ return Status;
+}
+
+
+/**
+ Send data over the socket
+
+ @retval EFI_SUCCESS The application is running normally
+ @retval Other The user stopped the application
+**/
+EFI_STATUS
+SocketSend (
+ )
+{
+ size_t BytesSent;
+ EFI_STATUS Status;
+ EFI_TPL TplPrevious;
+
+ //
+ // Restart the timer
+ //
+ TimerStart ( 1 * 1000 );
+
+ //
+ // Loop until the connection breaks or the user stops
+ //
+ do {
+ //
+ // Check for user stop request
+ //
+ Status = ControlCCheck ( );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Send some bytes
+ //
+ BytesSent = write ( Socket, &Buffer[0], sizeof ( Buffer ));
+ if ( -1 == BytesSent ) {
+ DEBUG (( DEBUG_INFO,
+ "ERROR: send failed, errno: %d\r\n",
+ errno ));
+Print ( L"ERROR: send failed, errno: %d\r\n", errno );
+
+ //
+ // Try again
+ //
+ Status = EFI_SUCCESS;
+
+//
+// Exit now
+//
+Status = EFI_NOT_STARTED;
+ break;
+ }
+
+ //
+ // Synchronize with the TimerCallback routine
+ //
+ TplPrevious = gBS->RaiseTPL ( TPL_DATASOURCE );
+
+ //
+ // Account for the data sent
+ //
+ TotalBytesSent += BytesSent;
+
+ //
+ // Release the TimerCallback routine synchronization
+ //
+ gBS->RestoreTPL ( TplPrevious );
+ } while ( !EFI_ERROR ( Status ));
+
+ //
+ // Return the operation status
+ //
+ return Status;
+}
+
+
+/**
+ Open the network connection and send the data.
+
+ @retval EFI_SUCCESS Continue looping
+ @retval other Stopped by user's Control-C input
+
+**/
+EFI_STATUS
+SocketOpen (
+ )
+{
+ EFI_STATUS Status;
+
+ //
+ // Use do/while and break instead of goto
+ //
+ do {
+ //
+ // Wait for the network layer to initialize
+ //
+ Status = SocketNew ( RemoteHostAddress.sin6_family );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Wait for the remote network application to start
+ //
+ Status = SocketConnect ( );
+Print ( L"Status: %r\r\n", Status );
+ if ( EFI_NOT_STARTED == Status ) {
+ Status = SocketClose ( );
+ continue;
+ }
+ else if ( EFI_SUCCESS != Status ) {
+ //
+ // Control-C
+ //
+ break;
+ }
+
+ //
+ // Send data until the connection breaks
+ //
+ Status = SocketSend ( );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ } while ( FALSE );
+
+ //
+ // Return the operation status
+ //
+Print ( L"Returning Status: %r\r\n", Status );
+ return Status;
+}
+
+
+/**
+ Close the TCP connection
+
+ @retval EFI_SUCCESS The application is running normally
+ @retval Other The user stopped the application
+**/
+EFI_STATUS
+Tcp4Close (
+ )
+{
+ UINTN Index;
+ UINT8 * pIpAddress;
+ EFI_STATUS Status;
+
+ //
+ // Close the port
+ //
+ if ( bTcp4Connected ) {
+ Tcp4CloseToken.AbortOnClose = TRUE;
+ Status = pTcp4Protocol->Close ( pTcp4Protocol,
+ &Tcp4CloseToken );
+ if ( EFI_ERROR ( Status )) {
+ DEBUG (( DEBUG_ERROR,
+ "ERROR - Failed to start the TCP port close, Status: %r\r\n",
+ Status ));
+ }
+ else {
+ Status = gBS->WaitForEvent ( 1,
+ &Tcp4CloseToken.CompletionToken.Event,
+ &Index );
+ if ( EFI_ERROR ( Status )) {
+ DEBUG (( DEBUG_ERROR,
+ "ERROR - Failed to wait for close event, Status: %r\r\n",
+ Status ));
+ }
+ else {
+ Status = Tcp4CloseToken.CompletionToken.Status;
+ if ( EFI_ERROR ( Status )) {
+ DEBUG (( DEBUG_ERROR,
+ "ERROR - Failed to close the TCP port, Status: %r\r\n",
+ Status ));
+ }
+ else {
+ DEBUG (( DEBUG_INFO,
+ "0x%08x: TCP port closed\r\n",
+ pTcp4Protocol ));
+ bTcp4Connected = FALSE;
+
+ //
+ // Display the port closed message
+ //
+ pIpAddress = (UINT8 *)&((struct sockaddr_in *)&RemoteHostAddress)->sin_addr.s_addr;
+ Print ( L"Closed connection to %d.%d.%d.%d:%d\r\n",
+ pIpAddress[0],
+ pIpAddress[1],
+ pIpAddress[2],
+ pIpAddress[3],
+ ntohs ( ((struct sockaddr_in *)&RemoteHostAddress)->sin_port ));
+ }
+ }
+ }
+ }
+
+ //
+ // Release the events
+ //
+ if ( NULL != Tcp4TxToken.CompletionToken.Event ) {
+ Status = gBS->CloseEvent ( Tcp4TxToken.CompletionToken.Event );
+ if ( !EFI_ERROR ( Status )) {
+ DEBUG (( DEBUG_INFO,
+ "0x%08x: TX event closed\r\n",
+ Tcp4TxToken.CompletionToken.Event ));
+ Tcp4TxToken.CompletionToken.Event = NULL;
+ }
+ else {
+ DEBUG (( DEBUG_ERROR,
+ "ERROR - Failed to close the Tcp4TxToken event, Status: %r\r\n",
+ Status ));
+ }
+ }
+
+ if ( NULL != Tcp4ListenToken.CompletionToken.Event ) {
+ Status = gBS->CloseEvent ( Tcp4ListenToken.CompletionToken.Event );
+ if ( !EFI_ERROR ( Status )) {
+ DEBUG (( DEBUG_INFO,
+ "0x%08x: Listen event closed\r\n",
+ Tcp4ListenToken.CompletionToken.Event ));
+ Tcp4ListenToken.CompletionToken.Event = NULL;
+ }
+ else {
+ DEBUG (( DEBUG_ERROR,
+ "ERROR - Failed to close the Tcp4ListenToken event, Status: %r\r\n",
+ Status ));
+ }
+ }
+
+ if ( NULL != Tcp4ConnectToken.CompletionToken.Event ) {
+ Status = gBS->CloseEvent ( Tcp4ConnectToken.CompletionToken.Event );
+ if ( !EFI_ERROR ( Status )) {
+ DEBUG (( DEBUG_INFO,
+ "0x%08x: Connect event closed\r\n",
+ Tcp4ConnectToken.CompletionToken.Event ));
+ Tcp4ConnectToken.CompletionToken.Event = NULL;
+ }
+ else {
+ DEBUG (( DEBUG_ERROR,
+ "ERROR - Failed to close the Tcp4ConnectToken event, Status: %r\r\n",
+ Status ));
+ }
+ }
+
+ if ( NULL != Tcp4CloseToken.CompletionToken.Event ) {
+ Status = gBS->CloseEvent ( Tcp4CloseToken.CompletionToken.Event );
+ if ( !EFI_ERROR ( Status )) {
+ DEBUG (( DEBUG_INFO,
+ "0x%08x: Close event closed\r\n",
+ Tcp4CloseToken.CompletionToken.Event ));
+ Tcp4CloseToken.CompletionToken.Event = NULL;
+ }
+ else {
+ DEBUG (( DEBUG_ERROR,
+ "ERROR - Failed to close the Tcp4CloseToken event, Status: %r\r\n",
+ Status ));
+ }
+ }
+
+ //
+ // Close the TCP protocol
+ //
+ if ( NULL != pTcp4Protocol ) {
+ Status = gBS->CloseProtocol ( Tcp4Handle,
+ &gEfiTcp4ProtocolGuid,
+ gImageHandle,
+ NULL );
+ if ( EFI_ERROR ( Status )) {
+ DEBUG (( DEBUG_ERROR,
+ "ERROR - Failed to close the TCP protocol, Status: %r\r\n",
+ Status ));
+ }
+ else {
+ DEBUG (( DEBUG_INFO,
+ "0x%08x: TCP4 protocol closed\r\n",
+ pTcp4Protocol ));
+ pTcp4Protocol = NULL;
+ }
+ }
+
+ //
+ // Done with the TCP service
+ //
+ if ( NULL != Tcp4Handle ) {
+ Status = pTcp4Service->DestroyChild ( pTcp4Service,
+ Tcp4Handle );
+ if ( EFI_ERROR ( Status )) {
+ DEBUG (( DEBUG_ERROR,
+ "ERROR - Failed to release TCP service handle, Status: %r\r\n",
+ Status ));
+ }
+ else {
+ DEBUG (( DEBUG_INFO,
+ "Ox%08x: TCP service closed\r\n",
+ Tcp4Handle ));
+ Tcp4Handle = NULL;
+ }
+ }
+
+ //
+ // Close the service protocol
+ //
+ if ( NULL != pTcp4Service ) {
+ Status = gBS->CloseProtocol ( Tcp4Controller,
+ &gEfiTcp4ServiceBindingProtocolGuid,
+ gImageHandle,
+ NULL );
+ if ( !EFI_ERROR ( Status )) {
+ DEBUG (( DEBUG_INFO,
+ "0x%08x: Controller closed gEfiTcp4ServiceBindingProtocolGuid protocol\r\n",
+ Tcp4Controller ));
+ pTcp4Service = NULL;
+ }
+ else {
+ DEBUG (( DEBUG_ERROR,
+ "ERROR - Failed to close the gEfiTcp4ServiceBindingProtocolGuid protocol, Status: %r\r\n",
+ Status ));
+ }
+ }
+ Tcp4Controller = NULL;
+ bTcp4Connecting = TRUE;
+
+ //
+ // Mark the connection as closed
+ //
+ Status = EFI_SUCCESS;
+
+ //
+ // Return the operation status
+ //
+ return Status;
+}
+
+
+/**
+ Locate TCP protocol
+
+ @retval EFI_SUCCESS Protocol found
+ @retval other Protocl not found
+**/
+EFI_STATUS
+Tcp4Locate (
+ )
+{
+ UINTN HandleCount;
+ EFI_HANDLE * pHandles;
+ UINT8 * pIpAddress;
+ EFI_STATUS Status;
+
+ //
+ // Use do/while and break instead of goto
+ //
+ do {
+ //
+ // Attempt to locate the next TCP adapter in the system
+ //
+ Status = gBS->LocateHandleBuffer ( ByProtocol,
+ &gEfiTcp4ServiceBindingProtocolGuid,
+ NULL,
+ &HandleCount,
+ &pHandles );
+ if ( EFI_ERROR ( Status )) {
+ DEBUG (( DEBUG_WARN,
+ "WARNING - No network controllers or TCP4 available, Status: %r\r\n",
+ Status ));
+ break;
+ }
+
+ //
+ // Wrap the index if necessary
+ //
+ if ( HandleCount <= Tcp4Index ) {
+ Tcp4Index = 0;
+
+ //
+ // Wait for the next timer tick
+ //
+ do {
+ } while ( !bTick );
+ bTick = FALSE;
+ }
+
+ //
+ // Display the connecting message
+ //
+ if ( bTcp4Connecting ) {
+ pIpAddress = (UINT8 *)&((struct sockaddr_in *)&RemoteHostAddress)->sin_addr.s_addr;
+ Print ( L"Connecting to %d.%d.%d.%d:%d\r\n",
+ pIpAddress[0],
+ pIpAddress[1],
+ pIpAddress[2],
+ pIpAddress[3],
+ ntohs ( ((struct sockaddr_in *)&RemoteHostAddress)->sin_port ));
+ bTcp4Connecting = FALSE;
+ }
+
+ //
+ // Open the network controller's service protocol
+ //
+ Tcp4Controller = pHandles[ Tcp4Index++ ];
+ Status = gBS->OpenProtocol (
+ Tcp4Controller,
+ &gEfiTcp4ServiceBindingProtocolGuid,
+ (VOID **) &pTcp4Service,
+ gImageHandle,
+ NULL,
+ EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL );
+ if ( EFI_ERROR ( Status )) {
+ DEBUG (( DEBUG_ERROR,
+ "ERROR - Failed to open gEfiTcp4ServiceBindingProtocolGuid on controller 0x%08x\r\n",
+ Tcp4Controller ));
+ Tcp4Controller = NULL;
+ break;
+ }
+ DEBUG (( DEBUG_INFO,
+ "0x%08x: Controller opened gEfiTcp4ServiceBindingProtocolGuid protocol\r\n",
+ Tcp4Controller ));
+
+ //
+ // Connect to the TCP service
+ //
+ Status = pTcp4Service->CreateChild ( pTcp4Service,
+ &Tcp4Handle );
+ if ( EFI_ERROR ( Status )) {
+ DEBUG (( DEBUG_ERROR,
+ "ERROR - Failed to open TCP service, Status: %r\r\n",
+ Status ));
+ Tcp4Handle = NULL;
+ break;
+ }
+ DEBUG (( DEBUG_INFO,
+ "Ox%08x: TCP service opened\r\n",
+ Tcp4Handle ));
+
+ //
+ // Locate the TCP protcol
+ //
+ Status = gBS->OpenProtocol ( Tcp4Handle,
+ &gEfiTcp4ProtocolGuid,
+ (VOID **)&pTcp4Protocol,
+ gImageHandle,
+ NULL,
+ EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL );
+ if ( EFI_ERROR ( Status )) {
+ DEBUG (( DEBUG_ERROR,
+ "ERROR - Failed to open the TCP protocol, Status: %r\r\n",
+ Status ));
+ pTcp4Protocol = NULL;
+ break;
+ }
+ DEBUG (( DEBUG_INFO,
+ "0x%08x: TCP4 protocol opened\r\n",
+ pTcp4Protocol ));
+ }while ( FALSE );
+
+ //
+ // Release the handle buffer
+ //
+ gBS->FreePool ( pHandles );
+
+ //
+ // Return the operation status
+ //
+ return Status;
+}
+
+
+/**
+ Send data over the TCP4 connection
+
+ @retval EFI_SUCCESS The application is running normally
+ @retval Other The user stopped the application
+**/
+EFI_STATUS
+Tcp4Send (
+ )
+{
+ UINTN Index;
+ EFI_TCP4_TRANSMIT_DATA Packet;
+ EFI_STATUS Status;
+ EFI_TPL TplPrevious;
+
+ //
+ // Restart the timer
+ //
+ TimerStart ( 1 * 1000 );
+
+ //
+ // Initialize the packet
+ //
+ Packet.DataLength = sizeof ( Buffer );
+ Packet.FragmentCount = 1;
+ Packet.Push = FALSE;
+ Packet.Urgent = FALSE;
+ Packet.FragmentTable[0].FragmentBuffer = &Buffer[0];
+ Packet.FragmentTable[0].FragmentLength = sizeof ( Buffer );
+ Tcp4TxToken.Packet.TxData = &Packet;
+
+ //
+ // Loop until the connection breaks or the user stops
+ //
+ do {
+ //
+ // Check for user stop request
+ //
+ Status = ControlCCheck ( );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Send some bytes
+ //
+ Status = pTcp4Protocol->Transmit ( pTcp4Protocol,
+ &Tcp4TxToken );
+ if ( EFI_ERROR ( Status )) {
+ DEBUG (( DEBUG_ERROR,
+ "ERROR - Failed to start the transmit, Status: %r\r\n",
+ Status ));
+
+ //
+ // Try again
+ //
+ Status = EFI_SUCCESS;
+ break;
+ }
+
+ //
+ // Wait for the transmit to complete
+ //
+ Status = gBS->WaitForEvent ( 1,
+ &Tcp4TxToken.CompletionToken.Event,
+ &Index );
+ if ( EFI_ERROR ( Status )) {
+ DEBUG (( DEBUG_ERROR,
+ "ERROR - Failed to wait for transmit completion, Status: %r\r\n",
+ Status ));
+
+ //
+ // Try again
+ //
+ Status = EFI_SUCCESS;
+ break;
+ }
+
+ //
+ // Get the transmit status
+ //
+ Status = Tcp4TxToken.CompletionToken.Status;
+ if ( EFI_ERROR ( Status )) {
+ DEBUG (( DEBUG_WARN,
+ "WARNING - Failed the transmission, Status: %r\r\n",
+ Status ));
+
+ //
+ // Try again
+ //
+ Status = EFI_SUCCESS;
+
+//
+// Exit now
+//
+Status = EFI_NOT_STARTED;
+ break;
+ }
+
+ //
+ // Synchronize with the TimerCallback routine
+ //
+ TplPrevious = gBS->RaiseTPL ( TPL_DATASOURCE );
+
+ //
+ // Account for the data sent
+ //
+ TotalBytesSent += Packet.DataLength;
+
+ //
+ // Release the TimerCallback routine synchronization
+ //
+ gBS->RestoreTPL ( TplPrevious );
+ } while ( !EFI_ERROR ( Status ));
+
+ //
+ // Return the operation status
+ //
+ return Status;
+}
+
+
+/**
+ Open the network connection and send the data.
+
+ @retval EFI_SUCCESS Continue looping
+ @retval other Stopped by user's Control-C input
+
+**/
+EFI_STATUS
+Tcp4Open (
+ )
+{
+ UINTN Index;
+ UINT8 * pIpAddress;
+ EFI_STATUS Status;
+
+ //
+ // Use do/while and break instead of goto
+ //
+ do {
+ //
+ // Locate the TCP protocol
+ //
+ Status = Tcp4Locate ( );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Create the necessary events
+ //
+ Status = gBS->CreateEvent ( 0,
+ TPL_CALLBACK,
+ NULL,
+ NULL,
+ &Tcp4CloseToken.CompletionToken.Event );
+ if ( EFI_ERROR ( Status )) {
+ DEBUG (( DEBUG_ERROR,
+ "ERROR - Failed to create the close event, Status: %r\r\n",
+ Status ));
+ Tcp4CloseToken.CompletionToken.Event = NULL;
+ break;
+ }
+ DEBUG (( DEBUG_INFO,
+ "0x%08x: Close event open\r\n",
+ Tcp4CloseToken.CompletionToken.Event ));
+
+ Status = gBS->CreateEvent ( 0,
+ TPL_CALLBACK,
+ NULL,
+ NULL,
+ &Tcp4ConnectToken.CompletionToken.Event );
+ if ( EFI_ERROR ( Status )) {
+ DEBUG (( DEBUG_ERROR,
+ "ERROR - Failed to create the connect event, Status: %r\r\n",
+ Status ));
+ Tcp4ConnectToken.CompletionToken.Event = NULL;
+ break;
+ }
+ DEBUG (( DEBUG_INFO,
+ "0x%08x: Connect event open\r\n",
+ Tcp4ConnectToken.CompletionToken.Event ));
+
+ Status = gBS->CreateEvent ( 0,
+ TPL_CALLBACK,
+ NULL,
+ NULL,
+ &Tcp4ListenToken.CompletionToken.Event );
+ if ( EFI_ERROR ( Status )) {
+ DEBUG (( DEBUG_ERROR,
+ "ERROR - Failed to create the listen event, Status: %r\r\n",
+ Status ));
+ Tcp4ListenToken.CompletionToken.Event = NULL;
+ break;
+ }
+ DEBUG (( DEBUG_INFO,
+ "0x%08x: Listen event open\r\n",
+ Tcp4ListenToken.CompletionToken.Event ));
+
+ Status = gBS->CreateEvent ( 0,
+ TPL_CALLBACK,
+ NULL,
+ NULL,
+ &Tcp4TxToken.CompletionToken.Event );
+ if ( EFI_ERROR ( Status )) {
+ DEBUG (( DEBUG_ERROR,
+ "ERROR - Failed to create the TX event, Status: %r\r\n",
+ Status ));
+ Tcp4TxToken.CompletionToken.Event = NULL;
+ break;
+ }
+ DEBUG (( DEBUG_INFO,
+ "0x%08x: TX event open\r\n",
+ Tcp4TxToken.CompletionToken.Event ));
+
+ //
+ // Configure the local TCP port
+ //
+ Tcp4ConfigData.TimeToLive = 255;
+ Tcp4ConfigData.TypeOfService = 0;
+ Tcp4ConfigData.ControlOption = NULL;
+ Tcp4ConfigData.AccessPoint.ActiveFlag = TRUE;
+ Tcp4ConfigData.AccessPoint.StationAddress.Addr[0] = 0;
+ Tcp4ConfigData.AccessPoint.StationAddress.Addr[1] = 0;
+ Tcp4ConfigData.AccessPoint.StationAddress.Addr[2] = 0;
+ Tcp4ConfigData.AccessPoint.StationAddress.Addr[3] = 0;
+ Tcp4ConfigData.AccessPoint.StationPort = 0;
+ Tcp4ConfigData.AccessPoint.RemoteAddress.Addr[0] = (UINT8) ((struct sockaddr_in *)&RemoteHostAddress)->sin_addr.s_addr;
+ Tcp4ConfigData.AccessPoint.RemoteAddress.Addr[1] = (UINT8)( ((struct sockaddr_in *)&RemoteHostAddress)->sin_addr.s_addr >> 8 );
+ Tcp4ConfigData.AccessPoint.RemoteAddress.Addr[2] = (UINT8)( ((struct sockaddr_in *)&RemoteHostAddress)->sin_addr.s_addr >> 16 );
+ Tcp4ConfigData.AccessPoint.RemoteAddress.Addr[3] = (UINT8)( ((struct sockaddr_in *)&RemoteHostAddress)->sin_addr.s_addr >> 24 );
+ Tcp4ConfigData.AccessPoint.RemotePort = ntohs (((struct sockaddr_in *)&RemoteHostAddress)->sin_port);
+ Tcp4ConfigData.AccessPoint.UseDefaultAddress = TRUE;
+ Tcp4ConfigData.AccessPoint.SubnetMask.Addr[0] = 0;
+ Tcp4ConfigData.AccessPoint.SubnetMask.Addr[1] = 0;
+ Tcp4ConfigData.AccessPoint.SubnetMask.Addr[2] = 0;
+ Tcp4ConfigData.AccessPoint.SubnetMask.Addr[3] = 0;
+ Status = pTcp4Protocol->Configure ( pTcp4Protocol,
+ &Tcp4ConfigData );
+ if ( EFI_ERROR ( Status )) {
+ DEBUG (( DEBUG_ERROR,
+ "ERROR - Failed to configure TCP port, Status: %r\r\n",
+ Status ));
+ break;
+ }
+ DEBUG (( DEBUG_INFO,
+ "0x%08x: TCP4 port configured\r\n",
+ pTcp4Protocol ));
+
+ //
+ // Connect to the remote TCP port
+ //
+ Status = pTcp4Protocol->Connect ( pTcp4Protocol,
+ &Tcp4ConnectToken );
+ if ( EFI_ERROR ( Status )) {
+ DEBUG (( DEBUG_ERROR,
+ "ERROR - Failed to start the connection to the remote system, Status: %r\r\n",
+ Status ));
+ break;
+ }
+ Status = gBS->WaitForEvent ( 1,
+ &Tcp4ConnectToken.CompletionToken.Event,
+ &Index );
+ if ( EFI_ERROR ( Status )) {
+ DEBUG (( DEBUG_ERROR,
+ "ERROR - Failed to wait for the connection, Status: %r\r\n",
+ Status ));
+ break;
+ }
+ Status = Tcp4ConnectToken.CompletionToken.Status;
+ if ( EFI_ERROR ( Status )) {
+ DEBUG (( DEBUG_WARN,
+ "WARNING - Failed to connect to the remote system, Status: %r\r\n",
+ Status ));
+ break;
+ }
+ DEBUG (( DEBUG_INFO,
+ "0x%08x: TCP4 port connected\r\n",
+ pTcp4Protocol ));
+ bTcp4Connected = TRUE;
+
+ //
+ // Display the connection
+ //
+ pIpAddress = (UINT8 *)&((struct sockaddr_in *)&RemoteHostAddress)->sin_addr.s_addr;
+ Print ( L"Connected to %d.%d.%d.%d:%d\r\n",
+ pIpAddress[0],
+ pIpAddress[1],
+ pIpAddress[2],
+ pIpAddress[3],
+ ntohs ( ((struct sockaddr_in *)&RemoteHostAddress)->sin_port ));
+ } while ( 0 );
+
+ if ( EFI_ERROR ( Status )) {
+ //
+ // Try again
+ //
+ Status = EFI_SUCCESS;
+ }
+ else {
+ //
+ // Semd data until the connection breaks
+ //
+ Status = Tcp4Send ( );
+ }
+
+ //
+ // Return the operation status
+ //
+ return Status;
+}
+
+
+/**
+ Handle the timer callback
+
+ @param [in] Event Event that caused this callback
+ @param [in] pContext Context for this routine
+**/
+VOID
+EFIAPI
+TimerCallback (
+ IN EFI_EVENT Event,
+ IN VOID * pContext
+ )
+{
+ UINT32 Average;
+ UINT64 BitsPerSecond;
+ UINT32 Index;
+ UINT64 TotalBytes;
+
+ //
+ // Notify the other code of the timer tick
+ //
+ bTick = TRUE;
+
+ //
+ // Update the average bytes per second
+ //
+ if ( 0 != TotalBytesSent ) {
+ BytesSent[ In ] = TotalBytesSent;
+ TotalBytesSent = 0;
+ In += 1;
+ if ( DATA_SAMPLES <= In ) {
+ In = 0;
+ }
+
+ //
+ // Separate the samples
+ //
+ if ( DATA_SAMPLES == Samples ) {
+ Print ( L"---------- Stable average ----------\r\n" );
+ }
+ Samples += 1;
+
+ //
+ // Compute the data rate
+ //
+ TotalBytes = 0;
+ for ( Index = 0; DATA_SAMPLES > Index; Index++ ) {
+ TotalBytes += BytesSent[ Index ];
+ }
+ Average = (UINT32)RShiftU64 ( TotalBytes, DATA_SAMPLE_SHIFT );
+ BitsPerSecond = Average * 8;
+
+ //
+ // Display the data rate
+ //
+ if (( RANGE_SWITCH >> 10 ) > Average ) {
+ Print ( L"Ave: %d Bytes/Sec, %Ld Bits/sec\r\n",
+ Average,
+ BitsPerSecond );
+ }
+ else {
+ BitsPerSecond /= 1000;
+ if ( RANGE_SWITCH > Average ) {
+ Print ( L"Ave: %d.%03d KiBytes/Sec, %Ld KBits/sec\r\n",
+ Average >> 10,
+ (( Average & 0x3ff ) * 1000 ) >> 10,
+ BitsPerSecond );
+ }
+ else {
+ BitsPerSecond /= 1000;
+ Average >>= 10;
+ if ( RANGE_SWITCH > Average ) {
+ Print ( L"Ave: %d.%03d MiBytes/Sec, %Ld MBits/sec\r\n",
+ Average >> 10,
+ (( Average & 0x3ff ) * 1000 ) >> 10,
+ BitsPerSecond );
+ }
+ else {
+ BitsPerSecond /= 1000;
+ Average >>= 10;
+ if ( RANGE_SWITCH > Average ) {
+ Print ( L"Ave: %d.%03d GiBytes/Sec, %Ld GBits/sec\r\n",
+ Average >> 10,
+ (( Average & 0x3ff ) * 1000 ) >> 10,
+ BitsPerSecond );
+ }
+ else {
+ BitsPerSecond /= 1000;
+ Average >>= 10;
+ if ( RANGE_SWITCH > Average ) {
+ Print ( L"Ave: %d.%03d TiBytes/Sec, %Ld TBits/sec\r\n",
+ Average >> 10,
+ (( Average & 0x3ff ) * 1000 ) >> 10,
+ BitsPerSecond );
+ }
+ else {
+ BitsPerSecond /= 1000;
+ Average >>= 10;
+ Print ( L"Ave: %d.%03d PiBytes/Sec, %Ld PBits/sec\r\n",
+ Average >> 10,
+ (( Average & 0x3ff ) * 1000 ) >> 10,
+ BitsPerSecond );
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+
+/**
+ Create the timer
+
+ @retval EFI_SUCCESS The timer was successfully created
+ @retval Other Timer initialization failed
+**/
+EFI_STATUS
+TimerCreate (
+ )
+{
+ EFI_STATUS Status;
+
+ //
+ // Create the timer
+ //
+ Status = gBS->CreateEvent ( EVT_TIMER | EVT_NOTIFY_SIGNAL,
+ TPL_DATASOURCE,
+ TimerCallback,
+ NULL,
+ &pTimer );
+ if ( EFI_ERROR ( Status )) {
+ DEBUG (( DEBUG_ERROR,
+ "ERROR - Failed to allocate the timer event, Status: %r\r\n",
+ Status ));
+ }
+ else {
+ DEBUG (( DEBUG_INFO,
+ "0x%08x: Timer created\r\n",
+ pTimer ));
+ }
+
+ //
+ // Return the operation status
+ //
+ return Status;
+}
+
+
+/**
+ Stop the timer
+
+ @retval EFI_SUCCESS The timer was stopped successfully
+ @retval Other The timer failed to stop
+**/
+EFI_STATUS
+TimerStop (
+ )
+{
+ EFI_STATUS Status;
+
+ //
+ // Assume success
+ //
+ Status = EFI_SUCCESS;
+
+ //
+ // Determine if the timer is running
+ //
+ if ( bTimerRunning ) {
+ //
+ // Stop the timer
+ //
+ Status = gBS->SetTimer ( pTimer,
+ TimerCancel,
+ 0 );
+ if ( EFI_ERROR ( Status )) {
+ DEBUG (( DEBUG_ERROR,
+ "ERROR - Failed to stop the timer, Status: %r\r\n",
+ Status ));
+ }
+ else {
+ //
+ // Timer timer is now stopped
+ //
+ bTimerRunning = FALSE;
+ DEBUG (( DEBUG_INFO,
+ "0x%08x: Timer stopped\r\n",
+ pTimer ));
+ }
+ }
+
+ //
+ // Return the operation status
+ //
+ return Status;
+}
+
+
+/**
+ Start the timer
+
+ @param [in] Milliseconds The number of milliseconds between timer callbacks
+
+ @retval EFI_SUCCESS The timer was successfully created
+ @retval Other Timer initialization failed
+**/
+EFI_STATUS
+TimerStart (
+ UINTN Milliseconds
+ )
+{
+ EFI_STATUS Status;
+ UINT64 TimeDelay;
+
+ //
+ // Stop the timer if necessary
+ //
+ Status = EFI_SUCCESS;
+ if ( bTimerRunning ) {
+ Status = TimerStop ( );
+ }
+ if ( !EFI_ERROR ( Status )) {
+ //
+ // Compute the new delay
+ //
+ TimeDelay = Milliseconds;
+ TimeDelay *= 1000 * 10;
+
+ //
+ // Start the timer
+ //
+ Status = gBS->SetTimer ( pTimer,
+ TimerPeriodic,
+ TimeDelay );
+ if ( EFI_ERROR ( Status )) {
+ DEBUG (( DEBUG_ERROR,
+ "ERROR - Failed to start the timer, Status: %r\r\n",
+ Status ));
+ }
+ else {
+ //
+ // The timer is now running
+ //
+ bTimerRunning = TRUE;
+ DEBUG (( DEBUG_INFO,
+ "0x%08x: Timer running\r\n",
+ pTimer ));
+ }
+ }
+
+ //
+ // Return the operation status
+ //
+ return Status;
+}
+
+
+/**
+ Destroy the timer
+
+ @retval EFI_SUCCESS The timer was destroyed successfully
+ @retval Other Failed to destroy the timer
+**/
+EFI_STATUS
+TimerDestroy (
+ )
+{
+ EFI_STATUS Status;
+
+ //
+ // Assume success
+ //
+ Status = EFI_SUCCESS;
+
+ //
+ // Determine if the timer is running
+ //
+ if ( bTimerRunning ) {
+ //
+ // Stop the timer
+ //
+ Status = TimerStop ( );
+ }
+ if (( !EFI_ERROR ( Status )) && ( NULL != pTimer )) {
+ //
+ // Done with this timer
+ //
+ Status = gBS->CloseEvent ( pTimer );
+ if ( EFI_ERROR ( Status )) {
+ DEBUG (( DEBUG_ERROR,
+ "ERROR - Failed to free the timer event, Status: %r\r\n",
+ Status ));
+ }
+ else {
+ DEBUG (( DEBUG_INFO,
+ "0x%08x: Timer Destroyed\r\n",
+ pTimer ));
+ pTimer = NULL;
+ }
+ }
+
+ //
+ // Return the operation status
+ //
+ return Status;
+}
+
+
+/**
+ Send data to the DataSink program to test a network's bandwidth.
+
+ @param [in] Argc The number of arguments
+ @param [in] Argv The argument value array
+
+ @retval 0 The application exited normally.
+ @retval Other An error occurred.
+**/
+int
+main (
+ IN int Argc,
+ IN char **Argv
+ )
+{
+ EFI_STATUS (* pClose) ();
+ EFI_STATUS (* pOpen) ();
+ EFI_STATUS Status;
+
+ DEBUG (( DEBUG_INFO,
+ "DataSource starting\r\n" ));
+
+ //
+ // Validate the command line
+ //
+ if ( 2 > Argc ) {
+ Print ( L"%s <remote IP address> [Use TCP]\r\n", Argv[0] );
+ return -1;
+ }
+
+ //
+ // Determine if TCP should be used
+ //
+ bTcp4 = (BOOLEAN)( 2 < Argc );
+
+ //
+ // Determine the support routines
+ //
+ if ( bTcp4 ) {
+ pOpen = Tcp4Open;
+ pClose = Tcp4Close;
+ bTcp4Connecting = TRUE;
+ }
+ else {
+ pOpen = SocketOpen;
+ pClose = SocketClose;
+ }
+
+ //
+ // Use for/break instead of goto
+ //
+ for ( ; ; ) {
+ //
+ // No bytes sent so far
+ //
+ TotalBytesSent = 0;
+ Samples = 0;
+ memset ( &BytesSent, 0, sizeof ( BytesSent ));
+
+ //
+ // Get the IP address
+ //
+ pRemoteHost = Argv[1];
+ Status = IpAddress ( );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Create the timer
+ //
+ bTick = TRUE;
+ Status = TimerCreate ( );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Loop forever abusing the specified system
+ //
+ do {
+ //
+ // Start a timer to perform connection polling and display updates
+ //
+ Status = TimerStart ( 2 * 1000 );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Open the network connection and send the data
+ //
+ Status = pOpen ( );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Done with the network connection
+ //
+ Status = pClose ( );
+ } while ( !EFI_ERROR ( Status ));
+
+ //
+ // Close the network connection if necessary
+ //
+ pClose ( );
+
+ //
+ // All done
+ //
+ break;
+ }
+
+ //
+ // Stop the timer if necessary
+ //
+ TimerStop ( );
+ TimerDestroy ( );
+
+ //
+ // Return the operation status
+ //
+ DEBUG (( DEBUG_INFO,
+ "DataSource exiting, Status: %r\r\n",
+ Status ));
+ return Status;
+}
diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/DataSource/DataSource.inf b/uefi/linaro-edk2/AppPkg/Applications/Sockets/DataSource/DataSource.inf
new file mode 100644
index 0000000..d088177
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/DataSource/DataSource.inf
@@ -0,0 +1,64 @@
+## @file
+# DataSource Application
+#
+# Copyright (c) 2011-2012, Intel Corporation
+# All rights reserved. This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = DataSource
+ FILE_GUID = 30EB0F26-FC0A-4fd2-B9C9-751EA2BB1980
+ MODULE_TYPE = UEFI_APPLICATION
+ VERSION_STRING = 1.0
+ ENTRY_POINT = ShellCEntryLib
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF EBC
+#
+
+[Sources]
+ DataSource.c
+
+
+[Pcd]
+ gAppPkgTokenSpaceGuid.DataSource_Port
+
+
+[Packages]
+ AppPkg/AppPkg.dec
+ MdePkg/MdePkg.dec
+ ShellPkg/ShellPkg.dec
+ StdLib/StdLib.dec
+
+
+[LibraryClasses]
+ BaseMemoryLib
+ BsdSocketLib
+ EfiSocketLib
+ DebugLib
+ LibC
+ ShellCEntryLib
+ UefiBootServicesTableLib
+ UefiLib
+# UseSocketDxe
+
+[Protocols]
+ gEfiTcp4ProtocolGuid
+ gEfiTcp4ServiceBindingProtocolGuid
+
+[BuildOptions]
+ INTEL:*_*_*_CC_FLAGS = /Qdiag-disable:181,186
+ MSFT:*_*_*_CC_FLAGS = /Od
+ GCC:*_*_*_CC_FLAGS = -O0 -Wno-unused-variable
+
diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/GetAddrInfo/GetAddrInfo.c b/uefi/linaro-edk2/AppPkg/Applications/Sockets/GetAddrInfo/GetAddrInfo.c
new file mode 100644
index 0000000..27da918
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/GetAddrInfo/GetAddrInfo.c
@@ -0,0 +1,120 @@
+/** @file
+ Test the getaddrinfo API
+
+ Copyright (c) 2011-2012, Intel Corporation
+ All rights reserved. This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <errno.h>
+#include <netdb.h>
+#include <string.h>
+#include <stdio.h>
+#include <Uefi.h>
+#include <unistd.h>
+
+#include <netinet/in.h>
+
+#include <sys/socket.h>
+
+char mBuffer[65536];
+
+
+/**
+ Test the getaddrinfo API
+
+ @param [in] Argc The number of arguments
+ @param [in] Argv The argument value array
+
+ @retval 0 The application exited normally.
+ @retval Other An error occurred.
+**/
+int
+main (
+ IN int Argc,
+ IN char **Argv
+ )
+{
+ int AppStatus;
+ int Index;
+ int MaxLen;
+ struct addrinfo * pAddrInfo;
+ char * pHostName;
+ struct addrinfo * pInfo;
+ char * pServerName;
+
+ //
+ // Determine if the host name is specified
+ //
+ AppStatus = 0;
+ if ( 1 == Argc ) {
+ printf ( "%s <host name> <server name>\r\n", Argv[0]);
+ }
+ else {
+ //
+ // Translate the host name
+ //
+ pHostName = Argv[1];
+ pServerName = NULL;
+ if ( 2 < Argc ) {
+ pServerName = Argv[2];
+ }
+ AppStatus = getaddrinfo ( pHostName,
+ pServerName,
+ NULL,
+ &pAddrInfo );
+ if ( 0 != AppStatus ) {
+ printf ( "ERROR - address info not found, errno: %d\r\n", AppStatus );
+ }
+ if ( NULL == pAddrInfo ) {
+ printf ( "ERROR - No address info structure allocated\r\n" );
+ }
+ else {
+ //
+ // Walk the list of addresses
+ //
+ pInfo = pAddrInfo;
+ while ( NULL != pInfo ) {
+ //
+ // Display this entry
+ //
+ printf ( "0x%08x: ai_flags\r\n", pInfo->ai_flags );
+ printf ( "0x%08x: ai_family\r\n", pInfo->ai_family );
+ printf ( "0x%08x: ai_socktype\r\n", pInfo->ai_socktype );
+ printf ( "0x%08x: ai_protocol\r\n", pInfo->ai_protocol );
+ printf ( "0x%08x: ai_addrlen\r\n", pInfo->ai_addrlen );
+ printf ( "%s: ai_canonname\r\n", pInfo->ai_canonname );
+ printf ( " 0x%02x: ai_addr->sa_len\r\n", (UINT8)pInfo->ai_addr->sa_len );
+ printf ( " 0x%02x: ai_addr->sa_family\r\n", (UINT8)pInfo->ai_addr->sa_family );
+ MaxLen = pInfo->ai_addr->sa_len;
+ if ( sizeof ( struct sockaddr_in6 ) < MaxLen ) {
+ MaxLen = sizeof ( struct sockaddr_in6 );
+ }
+ for ( Index = 0; ( MaxLen - 2 ) > Index; Index++ ) {
+ printf ( " 0x%02x: ai_addr->sa_data[%02d]\r\n", (UINT8)pInfo->ai_addr->sa_data [ Index ], Index );
+ }
+
+ //
+ // Set the next entry
+ //
+ pInfo = pInfo->ai_next;
+ }
+
+ //
+ // Done with this structures
+ //
+ freeaddrinfo ( pAddrInfo );
+ }
+ }
+
+ //
+ // All done
+ //
+ return AppStatus;
+}
diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/GetAddrInfo/GetAddrInfo.inf b/uefi/linaro-edk2/AppPkg/Applications/Sockets/GetAddrInfo/GetAddrInfo.inf
new file mode 100644
index 0000000..bcfb985
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/GetAddrInfo/GetAddrInfo.inf
@@ -0,0 +1,56 @@
+## @file
+# GetAddrInfo Application
+#
+# Copyright (c) 2011-2012, Intel Corporation
+# All rights reserved. This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = GetAddrInfo
+ FILE_GUID = 4C26DF71-EBE7-4dea-B5E2-0B5980433908
+ MODULE_TYPE = UEFI_APPLICATION
+ VERSION_STRING = 1.0
+ ENTRY_POINT = ShellCEntryLib
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF EBC
+#
+
+[Sources]
+ GetAddrInfo.c
+
+
+[Packages]
+ MdePkg/MdePkg.dec
+ ShellPkg/ShellPkg.dec
+ StdLib/StdLib.dec
+
+
+[LibraryClasses]
+ BaseMemoryLib
+ BsdSocketLib
+ DevMedia
+ EfiSocketLib
+ LibC
+ LibMath
+ LibNetUtil
+ ShellCEntryLib
+ UefiBootServicesTableLib
+# UseSocketDxe
+
+[BuildOptions]
+ INTEL:*_*_*_CC_FLAGS = /Qdiag-disable:181,186
+ MSFT:*_*_*_CC_FLAGS = /Od
+ GCC:*_*_*_CC_FLAGS = -O0 -Wno-unused-variable
+
diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/GetHostByAddr/GetHostByAddr.c b/uefi/linaro-edk2/AppPkg/Applications/Sockets/GetHostByAddr/GetHostByAddr.c
new file mode 100644
index 0000000..c096f43
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/GetHostByAddr/GetHostByAddr.c
@@ -0,0 +1,131 @@
+/** @file
+ Translate the port number into a service name
+
+ Copyright (c) 2011 - 2012, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+**/
+#include <errno.h>
+#include <netdb.h>
+#include <stdio.h>
+#include <string.h>
+#include <Uefi.h>
+#include <unistd.h>
+
+#include <arpa/nameser.h>
+#include <arpa/nameser_compat.h>
+
+#include <Library/DebugLib.h>
+#include <Library/UefiLib.h>
+
+#include <sys/socket.h>
+
+/**
+ Translate the IP address into a host name
+
+ @param[in] Argc The number of arguments
+ @param[in] Argv The argument value array
+
+ @retval 0 The application exited normally.
+ @retval Other An error occurred.
+**/
+int
+main (
+ IN int Argc,
+ IN char **Argv
+ )
+{
+ UINTN Index;
+ UINT8 IpAddress[4];
+ struct hostent * pHost;
+ UINT8 * pIpAddress;
+ char ** ppName;
+ UINT32 RemoteAddress[4];
+
+ //
+ // Determine if the IPv4 address is specified
+ //
+ if (( 2 != Argc )
+ || ( 4 != sscanf ( Argv[1],
+ "%d.%d.%d.%d",
+ &RemoteAddress[0],
+ &RemoteAddress[1],
+ &RemoteAddress[2],
+ &RemoteAddress[3]))
+ || ( 255 < RemoteAddress[0])
+ || ( 255 < RemoteAddress[1])
+ || ( 255 < RemoteAddress[2])
+ || ( 255 < RemoteAddress[3])) {
+ Print ( L"%a <IPv4 Address>\r\n", Argv[0]);
+ }
+ else {
+ //
+ // Translate the address into a host name
+ //
+ IpAddress[0] = (UINT8)RemoteAddress[0];
+ IpAddress[1] = (UINT8)RemoteAddress[1];
+ IpAddress[2] = (UINT8)RemoteAddress[2];
+ IpAddress[3] = (UINT8)RemoteAddress[3];
+ pHost = gethostbyaddr ( (const char *)&IpAddress[0], INADDRSZ, AF_INET );
+ if ( NULL == pHost ) {
+ Print ( L"ERROR - host not found, h_errno: %d\r\n", h_errno );
+ }
+ else {
+ pIpAddress = (UINT8 *)pHost->h_addr_list[ 0 ];
+ Print ( L"%d.%d.%d.%d, %a\r\n",
+ pIpAddress[0],
+ pIpAddress[1],
+ pIpAddress[2],
+ pIpAddress[3],
+ pHost->h_name );
+
+ //
+ // Display the other addresses
+ //
+ for ( Index = 1; NULL != pHost->h_addr_list[Index]; Index++ ) {
+ pIpAddress = (UINT8 *)pHost->h_addr_list[Index];
+ Print ( L"%d.%d.%d.%d\r\n",
+ pIpAddress[0],
+ pIpAddress[1],
+ pIpAddress[2],
+ pIpAddress[3]);
+ }
+
+ //
+ // Display the list of aliases
+ //
+ ppName = pHost->h_aliases;
+ if (( NULL == ppName ) || ( NULL == *ppName )) {
+ Print ( L"No aliases\r\n" );
+ }
+ else {
+ Print ( L"Aliases: " );
+ while ( NULL != *ppName ) {
+ //
+ // Display the alias
+ //
+ Print ( L"%a", *ppName );
+
+ //
+ // Set the next alias
+ //
+ ppName += 1;
+ if ( NULL != *ppName ) {
+ Print ( L", " );
+ }
+ }
+ Print ( L"\r\n" );
+ }
+ }
+ }
+
+ //
+ // All done
+ //
+ return errno;
+}
diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/GetHostByAddr/GetHostByAddr.inf b/uefi/linaro-edk2/AppPkg/Applications/Sockets/GetHostByAddr/GetHostByAddr.inf
new file mode 100644
index 0000000..d164510
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/GetHostByAddr/GetHostByAddr.inf
@@ -0,0 +1,58 @@
+## @file
+# GetHostByAddr Application
+#
+# Copyright (c) 2011-2012, Intel Corporation
+# All rights reserved. This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = GetHostByAddr
+ FILE_GUID = C31A6189-639A-458b-B040-D7D506CA8F4F
+ MODULE_TYPE = UEFI_APPLICATION
+ VERSION_STRING = 1.0
+ ENTRY_POINT = ShellCEntryLib
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF EBC
+#
+
+[Sources]
+ GetHostByAddr.c
+
+
+[Packages]
+ MdePkg/MdePkg.dec
+ ShellPkg/ShellPkg.dec
+ StdLib/StdLib.dec
+
+
+[LibraryClasses]
+ BaseMemoryLib
+ BsdSocketLib
+ DebugLib
+ DevMedia
+ EfiSocketLib
+ LibC
+ LibMath
+ LibNetUtil
+ ShellCEntryLib
+ UefiBootServicesTableLib
+ UefiLib
+# UseSocketDxe
+
+[BuildOptions]
+ INTEL:*_*_*_CC_FLAGS = /Qdiag-disable:181,186
+ MSFT:*_*_*_CC_FLAGS = /Od
+ GCC:*_*_*_CC_FLAGS = -O0 -Wno-unused-variable
+
diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/GetHostByDns/GetHostByDns.c b/uefi/linaro-edk2/AppPkg/Applications/Sockets/GetHostByDns/GetHostByDns.c
new file mode 100644
index 0000000..e87b04f
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/GetHostByDns/GetHostByDns.c
@@ -0,0 +1,73 @@
+/** @file
+ Translate the host name into an IP address
+
+ Copyright (c) 2011 - 2014, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials are licensed and made available under
+ the terms and conditions of the BSD License that accompanies this distribution.
+ The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+**/
+#include <errno.h>
+#include <netdb.h>
+#include <string.h>
+#include <Uefi.h>
+#include <unistd.h>
+
+#include <Library/DebugLib.h>
+#include <Library/UefiLib.h>
+
+#include <sys/socket.h>
+
+struct hostent * _gethostbydnsname (const char *, int);
+
+char mBuffer[65536];
+
+
+/** Translate the host name into an IP address
+
+ @param [in] Argc The number of arguments
+ @param [in] Argv The argument value array
+
+ @retval 0 The application exited normally.
+ @retval Other An error occurred.
+**/
+int
+main (
+ IN int Argc,
+ IN char **Argv
+ )
+{
+ UINT8 * pIpAddress;
+ struct hostent * pHost;
+
+ DEBUG (( DEBUG_INFO,
+ "%a starting\r\n",
+ Argv[0]));
+
+ // Determine if the host name is specified
+ if ( 1 == Argc ) {
+ Print ( L"%a <host name>\r\n", Argv[0]);
+ }
+ else {
+ // Translate the host name
+ pHost = _gethostbydnsname ( Argv[1], AF_INET );
+ if ( NULL == pHost ) {
+ Print ( L"ERROR - host not found, h_errno: %d\r\n", h_errno );
+ }
+ else {
+ pIpAddress = (UINT8 *)pHost->h_addr;
+ Print ( L"%a: Type %d, %d.%d.%d.%d\r\n",
+ pHost->h_name,
+ pHost->h_addrtype,
+ pIpAddress[0],
+ pIpAddress[1],
+ pIpAddress[2],
+ pIpAddress[3]);
+ }
+ }
+ // All done
+ return errno;
+}
diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/GetHostByDns/GetHostByDns.inf b/uefi/linaro-edk2/AppPkg/Applications/Sockets/GetHostByDns/GetHostByDns.inf
new file mode 100644
index 0000000..9856578
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/GetHostByDns/GetHostByDns.inf
@@ -0,0 +1,58 @@
+## @file
+# GetHostByDns Application
+#
+# Copyright (c) 2011-2012, Intel Corporation
+# All rights reserved. This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = GetHostByDns
+ FILE_GUID = 3698D2B0-E727-4537-A636-A8770736ABFB
+ MODULE_TYPE = UEFI_APPLICATION
+ VERSION_STRING = 1.0
+ ENTRY_POINT = ShellCEntryLib
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF EBC
+#
+
+[Sources]
+ GetHostByDns.c
+
+
+[Packages]
+ MdePkg/MdePkg.dec
+ ShellPkg/ShellPkg.dec
+ StdLib/StdLib.dec
+
+
+[LibraryClasses]
+ BaseMemoryLib
+ BsdSocketLib
+ DebugLib
+ DevMedia
+ EfiSocketLib
+ LibC
+ LibMath
+ LibNetUtil
+ ShellCEntryLib
+ UefiBootServicesTableLib
+ UefiLib
+# UseSocketDxe
+
+[BuildOptions]
+ INTEL:*_*_*_CC_FLAGS = /Qdiag-disable:181,186
+ MSFT:*_*_*_CC_FLAGS = /Od
+ GCC:*_*_*_CC_FLAGS = -O0 -Wno-unused-variable
+
diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/GetHostByName/GetHostByName.c b/uefi/linaro-edk2/AppPkg/Applications/Sockets/GetHostByName/GetHostByName.c
new file mode 100644
index 0000000..4d4fe54
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/GetHostByName/GetHostByName.c
@@ -0,0 +1,107 @@
+/** @file
+ Translate the host name into an IP address
+
+ Copyright (c) 2011 - 2014, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials are licensed and made available under
+ the terms and conditions of the BSD License that accompanies this distribution.
+ The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+**/
+#include <errno.h>
+#include <netdb.h>
+#include <string.h>
+#include <Uefi.h>
+#include <unistd.h>
+
+#include <Library/DebugLib.h>
+#include <Library/UefiLib.h>
+
+#include <sys/socket.h>
+
+char mBuffer[65536];
+
+
+/** Translate the host name into an IP address
+
+ @param[in] Argc The number of arguments
+ @param[in] Argv The argument value array
+
+ @retval 0 The application exited normally.
+ @retval Other An error occurred.
+**/
+int
+main (
+ IN int Argc,
+ IN char **Argv
+ )
+{
+ UINTN Index;
+ struct hostent * pHost;
+ UINT8 * pIpAddress;
+ char ** ppName;
+
+ DEBUG (( DEBUG_INFO,
+ "%a starting\r\n",
+ Argv[0]));
+
+ // Determine if the host name is specified
+ if ( 1 == Argc ) {
+ Print ( L"%a <host name>\r\n", Argv[0]);
+ }
+ else {
+ // Translate the host name
+ pHost = gethostbyname ( Argv[1]);
+ if ( NULL == pHost ) {
+ Print ( L"ERROR - host not found, h_errno: %d\r\n", h_errno );
+ }
+ else {
+ pIpAddress = (UINT8 *)pHost->h_addr;
+ Print ( L"%d.%d.%d.%d, Type %d, %a\r\n",
+ pIpAddress[0],
+ pIpAddress[1],
+ pIpAddress[2],
+ pIpAddress[3],
+ pHost->h_addrtype,
+ pHost->h_name );
+
+ // Display the other addresses
+ for ( Index = 1; NULL != pHost->h_addr_list[Index]; Index++ ) {
+ pIpAddress = (UINT8 *)pHost->h_addr_list[Index];
+ Print ( L"%d.%d.%d.%d\r\n",
+ pIpAddress[0],
+ pIpAddress[1],
+ pIpAddress[2],
+ pIpAddress[3]);
+ }
+
+ // Display the list of aliases
+ ppName = pHost->h_aliases;
+ if (( NULL == ppName ) || ( NULL == *ppName )) {
+ Print ( L"No aliases\r\n" );
+ }
+ else {
+ Print ( L"Aliases: " );
+ while ( NULL != *ppName ) {
+ //
+ // Display the alias
+ //
+ Print ( L"%a", *ppName );
+
+ //
+ // Set the next alias
+ //
+ ppName += 1;
+ if ( NULL != *ppName ) {
+ Print ( L", " );
+ }
+ }
+ Print ( L"\r\n" );
+ }
+ }
+ }
+ // All done
+ return errno;
+}
diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/GetHostByName/GetHostByName.inf b/uefi/linaro-edk2/AppPkg/Applications/Sockets/GetHostByName/GetHostByName.inf
new file mode 100644
index 0000000..a6f001a
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/GetHostByName/GetHostByName.inf
@@ -0,0 +1,58 @@
+## @file
+# GetHostByName Application
+#
+# Copyright (c) 2011-2012, Intel Corporation
+# All rights reserved. This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = GetHostByName
+ FILE_GUID = 70FB9CE0-2CB1-4fd7-80EE-AB4B6CF4B43F
+ MODULE_TYPE = UEFI_APPLICATION
+ VERSION_STRING = 1.0
+ ENTRY_POINT = ShellCEntryLib
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF EBC
+#
+
+[Sources]
+ GetHostByName.c
+
+
+[Packages]
+ MdePkg/MdePkg.dec
+ ShellPkg/ShellPkg.dec
+ StdLib/StdLib.dec
+
+
+[LibraryClasses]
+ BaseMemoryLib
+ BsdSocketLib
+ DebugLib
+ DevMedia
+ EfiSocketLib
+ LibC
+ LibMath
+ LibNetUtil
+ ShellCEntryLib
+ UefiBootServicesTableLib
+ UefiLib
+# UseSocketDxe
+
+[BuildOptions]
+ INTEL:*_*_*_CC_FLAGS = /Qdiag-disable:181,186
+ MSFT:*_*_*_CC_FLAGS = /Od
+ GCC:*_*_*_CC_FLAGS = -O0 -Wno-unused-variable
+
diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/GetNameInfo/GetNameInfo.c b/uefi/linaro-edk2/AppPkg/Applications/Sockets/GetNameInfo/GetNameInfo.c
new file mode 100644
index 0000000..d6fafde
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/GetNameInfo/GetNameInfo.c
@@ -0,0 +1,120 @@
+/** @file
+ Test the getnameinfo API
+
+ Copyright (c) 2011-2012, Intel Corporation
+ All rights reserved. This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <errno.h>
+#include <netdb.h>
+#include <string.h>
+#include <stdio.h>
+#include <Uefi.h>
+#include <unistd.h>
+
+#include <netinet/in.h>
+
+#include <sys/socket.h>
+
+char mBuffer[65536];
+char mHostName[256];
+char mServiceName[256];
+
+/**
+ Test the getnameinfo API
+
+ @param [in] Argc The number of arguments
+ @param [in] Argv The argument value array
+
+ @retval 0 The application exited normally.
+ @retval Other An error occurred.
+**/
+int
+main (
+ IN int Argc,
+ IN char **Argv
+ )
+{
+ int AppStatus;
+ struct addrinfo * pAddrInfo;
+ char * pHostName;
+ struct addrinfo * pInfo;
+ char * pServerName;
+
+ //
+ // Determine if the host name is specified
+ //
+ AppStatus = 0;
+ if ( 1 == Argc ) {
+ printf ( "%s <host address> <server name>\r\n", Argv[0]);
+ }
+ else {
+ //
+ // Translate the host name
+ //
+ pHostName = Argv[1];
+ pServerName = NULL;
+ if ( 2 < Argc ) {
+ pServerName = Argv[2];
+ }
+ AppStatus = getaddrinfo ( pHostName,
+ pServerName,
+ NULL,
+ &pAddrInfo );
+ if ( 0 != AppStatus ) {
+ printf ( "ERROR - address info not found, errno: %d\r\n", AppStatus );
+ }
+ if ( NULL == pAddrInfo ) {
+ printf ( "ERROR - No address info structure allocated\r\n" );
+ }
+ else {
+ //
+ // Walk the list of names
+ //
+ pInfo = pAddrInfo;
+ while ( NULL != pInfo ) {
+ //
+ // Get the name info
+ //
+ AppStatus = getnameinfo ((struct sockaddr *)pInfo->ai_addr,
+ pInfo->ai_addrlen,
+ &mHostName[0],
+ sizeof ( mHostName ),
+ &mServiceName[0],
+ sizeof ( mServiceName ),
+ 0 );
+ if ( 0 != AppStatus ) {
+ break;
+ }
+
+ //
+ // Display this entry
+ //
+ printf ( "%s: HostName\r\n", &mHostName[0]);
+ printf ( "%s: Service Name\r\n", &mServiceName[0]);
+
+ //
+ // Set the next entry
+ //
+ pInfo = pInfo->ai_next;
+ }
+
+ //
+ // Done with this structures
+ //
+ freeaddrinfo ( pAddrInfo );
+ }
+ }
+
+ //
+ // All done
+ //
+ return AppStatus;
+}
diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/GetNameInfo/GetNameInfo.inf b/uefi/linaro-edk2/AppPkg/Applications/Sockets/GetNameInfo/GetNameInfo.inf
new file mode 100644
index 0000000..87f8910
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/GetNameInfo/GetNameInfo.inf
@@ -0,0 +1,56 @@
+## @file
+# GetNameInfo Application
+#
+# Copyright (c) 2011-2012, Intel Corporation
+# All rights reserved. This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = GetNameInfo
+ FILE_GUID = 553087F6-BAAC-4d7f-97B4-31D8179AAE15
+ MODULE_TYPE = UEFI_APPLICATION
+ VERSION_STRING = 1.0
+ ENTRY_POINT = ShellCEntryLib
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF EBC
+#
+
+[Sources]
+ GetNameInfo.c
+
+
+[Packages]
+ MdePkg/MdePkg.dec
+ ShellPkg/ShellPkg.dec
+ StdLib/StdLib.dec
+
+
+[LibraryClasses]
+ BaseMemoryLib
+ BsdSocketLib
+ DevMedia
+ EfiSocketLib
+ LibC
+ LibMath
+ LibNetUtil
+ ShellCEntryLib
+ UefiBootServicesTableLib
+# UseSocketDxe
+
+[BuildOptions]
+ INTEL:*_*_*_CC_FLAGS = /Qdiag-disable:181,186
+ MSFT:*_*_*_CC_FLAGS = /Od
+ GCC:*_*_*_CC_FLAGS = -O0 -Wno-unused-variable
+
diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/GetNetByAddr/GetNetByAddr.c b/uefi/linaro-edk2/AppPkg/Applications/Sockets/GetNetByAddr/GetNetByAddr.c
new file mode 100644
index 0000000..156aa2b
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/GetNetByAddr/GetNetByAddr.c
@@ -0,0 +1,89 @@
+/** @file
+ Translate the IPv4 address into a network name
+
+ Copyright (c) 2011-2012, Intel Corporation
+ All rights reserved. This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <errno.h>
+#include <netdb.h>
+#include <stdio.h>
+#include <string.h>
+#include <Uefi.h>
+#include <unistd.h>
+
+#include <Library/DebugLib.h>
+#include <Library/UefiLib.h>
+
+#include <sys/socket.h>
+
+/**
+ Translate the IPv4 address into a network name
+
+ @param [in] Argc The number of arguments
+ @param [in] Argv The argument value array
+
+ @retval 0 The application exited normally.
+ @retval Other An error occurred.
+**/
+int
+main (
+ IN int Argc,
+ IN char **Argv
+ )
+{
+ UINT32 RemoteAddress[4];
+ UINT8 IpAddress[4];
+ struct netent * pNetwork;
+
+ //
+ // Determine if the IPv4 address is specified
+ //
+ if (( 2 != Argc )
+ || ( 4 != sscanf ( Argv[1],
+ "%d.%d.%d.%d",
+ &RemoteAddress[0],
+ &RemoteAddress[1],
+ &RemoteAddress[2],
+ &RemoteAddress[3]))
+ || ( 255 < RemoteAddress[0])
+ || ( 255 < RemoteAddress[1])
+ || ( 255 < RemoteAddress[2])
+ || ( 255 < RemoteAddress[3])) {
+ Print ( L"%a <IPv4 Address>\r\n", Argv[0]);
+ }
+ else {
+ //
+ // Translate the address into a network name
+ //
+ IpAddress[0] = (UINT8)RemoteAddress[0];
+ IpAddress[1] = (UINT8)RemoteAddress[1];
+ IpAddress[2] = (UINT8)RemoteAddress[2];
+ IpAddress[3] = (UINT8)RemoteAddress[3];
+ pNetwork = getnetbyaddr ( *(uint32_t *)&IpAddress[0], AF_INET );
+ if ( NULL == pNetwork ) {
+ Print ( L"ERROR - network not found, errno: %d\r\n", errno );
+ }
+ else {
+ Print ( L"%a: %d.%d.%d.%d, 0x%08x\r\n",
+ pNetwork->n_name,
+ IpAddress[0],
+ IpAddress[1],
+ IpAddress[2],
+ IpAddress[3],
+ pNetwork->n_net );
+ }
+ }
+
+ //
+ // All done
+ //
+ return errno;
+}
diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/GetNetByAddr/GetNetByAddr.inf b/uefi/linaro-edk2/AppPkg/Applications/Sockets/GetNetByAddr/GetNetByAddr.inf
new file mode 100644
index 0000000..f1b3954
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/GetNetByAddr/GetNetByAddr.inf
@@ -0,0 +1,58 @@
+## @file
+# GetNetByAddr Application
+#
+# Copyright (c) 2011-2012, Intel Corporation
+# All rights reserved. This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = GetNetByAddr
+ FILE_GUID = 22198FD5-4835-4842-BF31-EB957C7DD70D
+ MODULE_TYPE = UEFI_APPLICATION
+ VERSION_STRING = 1.0
+ ENTRY_POINT = ShellCEntryLib
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF EBC
+#
+
+[Sources]
+ GetNetByAddr.c
+
+
+[Packages]
+ MdePkg/MdePkg.dec
+ ShellPkg/ShellPkg.dec
+ StdLib/StdLib.dec
+
+
+[LibraryClasses]
+ BaseMemoryLib
+ BsdSocketLib
+ DebugLib
+ DevMedia
+ EfiSocketLib
+ LibC
+ LibMath
+ LibNetUtil
+ ShellCEntryLib
+ UefiBootServicesTableLib
+ UefiLib
+# UseSocketDxe
+
+[BuildOptions]
+ INTEL:*_*_*_CC_FLAGS = /Qdiag-disable:181,186
+ MSFT:*_*_*_CC_FLAGS = /Od
+ GCC:*_*_*_CC_FLAGS = -O0 -Wno-unused-variable
+
diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/GetNetByName/GetNetByName.c b/uefi/linaro-edk2/AppPkg/Applications/Sockets/GetNetByName/GetNetByName.c
new file mode 100644
index 0000000..7ce741c
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/GetNetByName/GetNetByName.c
@@ -0,0 +1,71 @@
+/** @file
+ Translate the network name into an IP address
+
+ Copyright (c) 2011 - 2014, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials are licensed and made available under
+ the terms and conditions of the BSD License that accompanies this distribution.
+ The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+**/
+#include <errno.h>
+#include <netdb.h>
+#include <string.h>
+#include <Uefi.h>
+#include <unistd.h>
+
+#include <Library/DebugLib.h>
+#include <Library/UefiLib.h>
+
+#include <sys/socket.h>
+
+char mBuffer[65536];
+
+
+/** Translate the network name into an IP address
+
+ @param[in] Argc The number of arguments
+ @param[in] Argv The argument value array
+
+ @retval 0 The application exited normally.
+ @retval Other An error occurred.
+**/
+int
+main (
+ IN int Argc,
+ IN char **Argv
+ )
+{
+ UINT8 * pIpAddress;
+ struct netent * pNetwork;
+
+ DEBUG (( DEBUG_INFO,
+ "%a starting\r\n",
+ Argv[0]));
+
+ // Determine if the network name is specified
+ if ( 1 == Argc ) {
+ Print ( L"%a <network name>\r\n", Argv[0]);
+ }
+ else {
+ // Translate the net name
+ pNetwork = getnetbyname ( Argv[1]);
+ if ( NULL == pNetwork ) {
+ Print ( L"ERROR - network not found, errno: %d\r\n", errno );
+ }
+ else {
+ pIpAddress = (UINT8 *)(UINTN)&pNetwork->n_net;
+ Print ( L"%a: Type %d, %d.%d.%d.%d\r\n",
+ pNetwork->n_name,
+ pNetwork->n_addrtype,
+ pIpAddress[0],
+ pIpAddress[1],
+ pIpAddress[2],
+ pIpAddress[3]);
+ }
+ }
+ // All done
+ return errno;
+}
diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/GetNetByName/GetNetByName.inf b/uefi/linaro-edk2/AppPkg/Applications/Sockets/GetNetByName/GetNetByName.inf
new file mode 100644
index 0000000..bfb1cd6
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/GetNetByName/GetNetByName.inf
@@ -0,0 +1,58 @@
+## @file
+# GetNetByName Application
+#
+# Copyright (c) 2011-2012, Intel Corporation
+# All rights reserved. This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = GetNetByName
+ FILE_GUID = DAF7B0E6-32DE-4619-B63A-2B9173A75B14
+ MODULE_TYPE = UEFI_APPLICATION
+ VERSION_STRING = 1.0
+ ENTRY_POINT = ShellCEntryLib
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF EBC
+#
+
+[Sources]
+ GetNetByName.c
+
+
+[Packages]
+ MdePkg/MdePkg.dec
+ ShellPkg/ShellPkg.dec
+ StdLib/StdLib.dec
+
+
+[LibraryClasses]
+ BaseMemoryLib
+ BsdSocketLib
+ DebugLib
+ DevMedia
+ EfiSocketLib
+ LibC
+ LibMath
+ LibNetUtil
+ ShellCEntryLib
+ UefiBootServicesTableLib
+ UefiLib
+# UseSocketDxe
+
+[BuildOptions]
+ INTEL:*_*_*_CC_FLAGS = /Qdiag-disable:181,186
+ MSFT:*_*_*_CC_FLAGS = /Od
+ GCC:*_*_*_CC_FLAGS = -O0 -Wno-unused-variable
+
diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/GetServByName/GetServByName.c b/uefi/linaro-edk2/AppPkg/Applications/Sockets/GetServByName/GetServByName.c
new file mode 100644
index 0000000..dede76b
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/GetServByName/GetServByName.c
@@ -0,0 +1,64 @@
+/** @file
+ Translate the service name into a port number
+
+ Copyright (c) 2011 - 2014, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials are licensed and made available under
+ the terms and conditions of the BSD License that accompanies this distribution.
+ The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+**/
+#include <errno.h>
+#include <netdb.h>
+#include <string.h>
+#include <Uefi.h>
+#include <unistd.h>
+
+#include <Library/DebugLib.h>
+#include <Library/UefiLib.h>
+
+#include <sys/socket.h>
+
+char mBuffer[65536];
+
+
+/** Translate the service name into a port number
+
+ @param[in] Argc The number of arguments
+ @param[in] Argv The argument value array
+
+ @retval 0 The application exited normally.
+ @retval Other An error occurred.
+**/
+int
+main (
+ IN int Argc,
+ IN char **Argv
+ )
+{
+ int PortNumber;
+ struct servent * pService;
+
+ // Determine if the service name is specified
+ if ( 1 == Argc ) {
+ Print ( L"%a <service name>\r\n", Argv[0]);
+ }
+ else {
+ // Translate the service name
+ pService = getservbyname ( Argv[1], NULL );
+ if ( NULL == pService ) {
+ Print ( L"ERROR - service not found, errno: %d\r\n", errno );
+ }
+ else {
+ PortNumber = htons ( pService->s_port );
+ Print ( L"%a: %d, %a\r\n",
+ pService->s_name,
+ PortNumber,
+ pService->s_proto );
+ }
+ }
+ // All done
+ return errno;
+}
diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/GetServByName/GetServByName.inf b/uefi/linaro-edk2/AppPkg/Applications/Sockets/GetServByName/GetServByName.inf
new file mode 100644
index 0000000..1b66e50
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/GetServByName/GetServByName.inf
@@ -0,0 +1,58 @@
+## @file
+# GetServByName Application
+#
+# Copyright (c) 2011-2012, Intel Corporation
+# All rights reserved. This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = GetServByName
+ FILE_GUID = 5D1F3F9E-8CEE-4299-93C2-4C64EBB58977
+ MODULE_TYPE = UEFI_APPLICATION
+ VERSION_STRING = 1.0
+ ENTRY_POINT = ShellCEntryLib
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF EBC
+#
+
+[Sources]
+ GetServByName.c
+
+
+[Packages]
+ MdePkg/MdePkg.dec
+ ShellPkg/ShellPkg.dec
+ StdLib/StdLib.dec
+
+
+[LibraryClasses]
+ BaseMemoryLib
+ BsdSocketLib
+ DebugLib
+ DevMedia
+ EfiSocketLib
+ LibC
+ LibMath
+ LibNetUtil
+ ShellCEntryLib
+ UefiBootServicesTableLib
+ UefiLib
+# UseSocketDxe
+
+[BuildOptions]
+ INTEL:*_*_*_CC_FLAGS = /Qdiag-disable:181,186
+ MSFT:*_*_*_CC_FLAGS = /Od
+ GCC:*_*_*_CC_FLAGS = -O0 -Wno-unused-variable
+
diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/GetServByPort/GetServByPort.c b/uefi/linaro-edk2/AppPkg/Applications/Sockets/GetServByPort/GetServByPort.c
new file mode 100644
index 0000000..69441e1
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/GetServByPort/GetServByPort.c
@@ -0,0 +1,65 @@
+/** @file
+ Translate the port number into a service name
+
+ Copyright (c) 2011 - 2014, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials are licensed and made available under
+ the terms and conditions of the BSD License that accompanies this distribution.
+ The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+**/
+#include <errno.h>
+#include <netdb.h>
+#include <stdio.h>
+#include <string.h>
+#include <Uefi.h>
+#include <unistd.h>
+
+#include <Library/DebugLib.h>
+#include <Library/UefiLib.h>
+
+#include <sys/socket.h>
+
+char mBuffer[65536];
+
+
+/** Translate the port number into a service name
+
+ @param[in] Argc The number of arguments
+ @param[in] Argv The argument value array
+
+ @retval 0 The application exited normally.
+ @retval Other An error occurred.
+**/
+int
+main (
+ IN int Argc,
+ IN char **Argv
+ )
+{
+ int PortNumber;
+ struct servent * pService;
+
+ // Determine if the service name is specified
+ if (( 2 != Argc )
+ || ( 1 != sscanf ( Argv[1], "%d", &PortNumber ))) {
+ Print ( L"%a <port number>\r\n", Argv[0]);
+ }
+ else {
+ // Translate the port number
+ pService = getservbyport ( htons ( PortNumber ), NULL );
+ if ( NULL == pService ) {
+ Print ( L"ERROR - service not found, errno: %d\r\n", errno );
+ }
+ else {
+ Print ( L"%a: %d, %a\r\n",
+ pService->s_name,
+ PortNumber,
+ pService->s_proto );
+ }
+ }
+ // All done
+ return errno;
+}
diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/GetServByPort/GetServByPort.inf b/uefi/linaro-edk2/AppPkg/Applications/Sockets/GetServByPort/GetServByPort.inf
new file mode 100644
index 0000000..d2a387f
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/GetServByPort/GetServByPort.inf
@@ -0,0 +1,58 @@
+## @file
+# GetServByPort Application
+#
+# Copyright (c) 2011-2012, Intel Corporation
+# All rights reserved. This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = GetServByPort
+ FILE_GUID = 83381B06-2EEA-4cf3-9B5F-D75B9B5C93DE
+ MODULE_TYPE = UEFI_APPLICATION
+ VERSION_STRING = 1.0
+ ENTRY_POINT = ShellCEntryLib
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF EBC
+#
+
+[Sources]
+ GetServByPort.c
+
+
+[Packages]
+ MdePkg/MdePkg.dec
+ ShellPkg/ShellPkg.dec
+ StdLib/StdLib.dec
+
+
+[LibraryClasses]
+ BaseMemoryLib
+ BsdSocketLib
+ DebugLib
+ DevMedia
+ EfiSocketLib
+ LibC
+ LibMath
+ LibNetUtil
+ ShellCEntryLib
+ UefiBootServicesTableLib
+ UefiLib
+# UseSocketDxe
+
+[BuildOptions]
+ INTEL:*_*_*_CC_FLAGS = /Qdiag-disable:181,186
+ MSFT:*_*_*_CC_FLAGS = /Od
+ GCC:*_*_*_CC_FLAGS = -O0 -Wno-unused-variable
+
diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/OobRx/Main.c b/uefi/linaro-edk2/AppPkg/Applications/Sockets/OobRx/Main.c
new file mode 100644
index 0000000..b4a37e0
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/OobRx/Main.c
@@ -0,0 +1,44 @@
+/** @file
+ Out-of-band receive test application
+
+ Copyright (c) 2011-2012, Intel Corporation
+ All rights reserved. This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <OobRx.h>
+
+
+/**
+ Receive out-of-band messages from the remote system.
+
+ @param [in] Argc The number of arguments
+ @param [in] Argv The argument value array
+
+ @retval 0 The application exited normally.
+ @retval Other An error occurred.
+**/
+int
+main (
+ IN int Argc,
+ IN char **Argv
+ )
+{
+ int RetVal;
+
+ //
+ // Run the application
+ //
+ RetVal = OobRx ( Argc, Argv );
+
+ //
+ // Return the operation status
+ //
+ return RetVal;
+}
diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/OobRx/OobRx.c b/uefi/linaro-edk2/AppPkg/Applications/Sockets/OobRx/OobRx.c
new file mode 100644
index 0000000..40d056d
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/OobRx/OobRx.c
@@ -0,0 +1,253 @@
+/** @file
+ Windows version of the OOB Receive application
+
+ Copyright (c) 2011-2012, Intel Corporation
+ All rights reserved. This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <OobRx.h>
+
+UINT8 mBuffer[65536];
+
+
+/**
+ Run the OOB receive application
+
+ @param [in] ArgC Argument count
+ @param [in] ArgV Argument value array
+
+ @retval 0 Successfully operation
+ **/
+int
+OobRx (
+ IN int ArgC,
+ IN char **ArgV
+ )
+{
+ SOCKET a;
+ ssize_t BytesReceived;
+ struct sockaddr_in LocalPort;
+ UINT32 OobInLine;
+ UINT16 PortNumber;
+ struct timeval ReceiveTimeout;
+ struct sockaddr_in RemotePort;
+ socklen_t RemotePortLength;
+ int RetVal;
+ SOCKET s;
+ UINT32 TransmittedBefore;
+ UINT32 TransmittedDuring;
+ UINT32 TransmittedOob;
+ UINT32 TransmittedAfter;
+ UINT32 * pTransmittedBytes;
+
+ //
+ // Create the socket
+ //
+ s = socket ( AF_INET, SOCK_STREAM, IPPROTO_TCP );
+ if ( -1 == s ) {
+ RetVal = GET_ERRNO;
+ printf ( "ERROR - socket error, errno: %d\r\n", RetVal );
+ }
+ else {
+ //
+ // Use for/break; instead of goto
+ //
+ for ( ; ; ) {
+ //
+ // Bind the socket to a known port
+ //
+ PortNumber = OOB_RX_PORT;
+ memset ( &LocalPort, 0, sizeof ( LocalPort ));
+ SIN_LEN ( LocalPort ) = sizeof ( LocalPort );
+ SIN_FAMILY ( LocalPort ) = AF_INET;
+ SIN_ADDR ( LocalPort ) = 0;
+ SIN_PORT ( LocalPort ) = htons ( PortNumber );
+ RetVal = bind ( s,
+ (struct sockaddr *)&LocalPort,
+ sizeof ( LocalPort ));
+ if ( -1 == RetVal ) {
+ RetVal = GET_ERRNO;
+ printf ( "ERROR - bind error, errno: %d\r\n", RetVal );
+ break;
+ }
+
+ //
+ // Make the port available on the server
+ //
+ RetVal = listen ( s, 2 );
+ if ( -1 == RetVal ) {
+ RetVal = GET_ERRNO;
+ printf ( "ERROR - listen error, errno: %d\r\n", RetVal );
+ break;
+ }
+
+ //
+ // Wait for a connection to the known port
+ //
+ RemotePortLength = sizeof ( RemotePort );
+ a = accept ( s,
+ (struct sockaddr *)&RemotePort,
+ &RemotePortLength );
+ if ( -1 == a ) {
+ RetVal = GET_ERRNO;
+ printf ( "ERROR - accept error, errno: %d\r\n", RetVal );
+ break;
+ }
+
+ //
+ // Use for/break instead of goto
+ //
+ for ( ; ; ) {
+ //
+ // Set the receive timeout
+ //
+ ReceiveTimeout.tv_sec = 0;
+ ReceiveTimeout.tv_usec = 20 * 1000;
+ RetVal = setsockopt ( a,
+ SOL_SOCKET,
+ SO_RCVTIMEO,
+ (char *)&ReceiveTimeout,
+ sizeof ( ReceiveTimeout ));
+ if ( -1 == RetVal ) {
+ RetVal = GET_ERRNO;
+ printf ( "ERROR - setsockopt RCVTIMEO error, errno: %d\r\n", RetVal );
+ break;
+ }
+
+ //
+ // Select the OOB processing
+ //
+ OobInLine = ( 1 < ArgC );
+ RetVal = setsockopt ( s,
+ SOL_SOCKET,
+ SO_OOBINLINE,
+ (char *)&OobInLine,
+ sizeof ( OobInLine ));
+ if ( -1 == RetVal ) {
+ RetVal = GET_ERRNO;
+ printf ( "ERROR - setsockopt OOBINLINE error, errno: %d\r\n", RetVal );
+ break;
+ }
+ printf ( "%s\r\n", ( 0 != OobInLine ) ? "OOB messages are in-line"
+ : "OOB messages move to the head of the queue" );
+
+ //
+ // Receive data from the remote system
+ //
+ TransmittedBefore = 0;
+ TransmittedOob = 0;
+ TransmittedDuring = 0;
+ TransmittedAfter = 0;
+ pTransmittedBytes = &TransmittedBefore;
+ do {
+ //
+ // Attempt to receive OOB data
+ //
+ BytesReceived = recv ( a, &mBuffer[0], sizeof ( mBuffer ), MSG_OOB );
+ RetVal = (UINT32)BytesReceived;
+ if ( 0 < BytesReceived ) {
+ //
+ // Display the received OOB data
+ //
+ printf ( "%5Ld OOB bytes received\r\n", (UINT64)BytesReceived );
+
+ //
+ // Account for the bytes received
+ //
+ TransmittedOob += RetVal;
+ *pTransmittedBytes += TransmittedAfter;
+ TransmittedAfter = 0;
+ pTransmittedBytes = &TransmittedDuring;
+ }
+ else if ( -1 == BytesReceived ) {
+ //
+ // Check for connection timeout
+ //
+ RetVal = GET_ERRNO;
+ if ( RX_TIMEOUT_ERROR != RetVal ) {
+ //
+ // Receive error
+ //
+ printf ( "ERROR - recv OOB error, errno: %d\r\n", RetVal );
+ break;
+ }
+
+ //
+ // Ignore the timeout
+ // Try to receive normal data instead
+ //
+ BytesReceived = recv ( a, &mBuffer[0], sizeof ( mBuffer ), 0 );
+ RetVal = (UINT32)BytesReceived;
+ if ( 0 < BytesReceived ) {
+ //
+ // Display the received data
+ //
+ printf ( "%4Ld bytes received\r\n", (UINT64)BytesReceived );
+
+ //
+ // Account for the bytes received
+ //
+ TransmittedAfter += RetVal;
+ }
+ else if ( -1 == BytesReceived ) {
+ //
+ // Check for a timeout
+ //
+ RetVal = GET_ERRNO;
+ if ( RX_TIMEOUT_ERROR != RetVal ) {
+ printf ( "ERROR - recv error, errno: %d\r\n", RetVal );
+ break;
+ }
+ }
+ }
+ } while ( 0 != RetVal );
+
+ //
+ // Display the bytes received
+ //
+ if ( 0 == RetVal ) {
+ printf ( "Bytes before OOB: %8d\r\n", TransmittedBefore );
+ if ( 0 != TransmittedDuring ) {
+ printf ( "Bytes during OOB: %8d\r\n", TransmittedDuring );
+ }
+ printf ( "Out-of-band bytes: %8d\r\n", TransmittedOob );
+ printf ( "Bytes after OOB: %8d\r\n", TransmittedAfter );
+ printf ( " --------\r\n" );
+ printf ( "Total Bytes: %8d\r\n", TransmittedBefore
+ + TransmittedDuring
+ + TransmittedOob
+ + TransmittedAfter );
+ }
+
+ //
+ // Test complete
+ //
+ break;
+ }
+
+ //
+ // Close the test socket
+ //
+ CLOSE_SOCKET ( a );
+ break;
+ }
+
+ //
+ // Close the socket
+ //
+ CLOSE_SOCKET ( s );
+ printf ( "Socket closed\r\n" );
+ }
+
+ //
+ // Return the operation status
+ //
+ return RetVal;
+}
diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/OobRx/OobRx.h b/uefi/linaro-edk2/AppPkg/Applications/Sockets/OobRx/OobRx.h
new file mode 100644
index 0000000..0920029
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/OobRx/OobRx.h
@@ -0,0 +1,97 @@
+/** @file
+ Definitions for the OOB Receive application
+
+ Copyright (c) 2011-2012, Intel Corporation
+ All rights reserved. This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef _OOB_RX_H_
+#define _OOB_RX_H_
+
+//------------------------------------------------------------------------------
+// Include Files
+//------------------------------------------------------------------------------
+
+#ifdef BUILD_FOR_WINDOWS
+//
+// Build for Windows environment
+//
+
+#include <winsock2.h>
+
+#define CLOSE_SOCKET closesocket
+#define SIN_ADDR(port) port.sin_addr.S_un.S_addr
+#define SIN_FAMILY(port) port.sin_family
+#define SIN_LEN(port) port.sin_family
+#define SIN_PORT(port) port.sin_port
+#define GET_ERRNO WSAGetLastError ( )
+
+#define RX_TIMEOUT_ERROR WSAETIMEDOUT
+#define ssize_t int
+#define socklen_t int
+
+#else // BUILD_FOR_WINDOWS
+//
+// Build for EFI environment
+//
+
+#include <Uefi.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <netinet/in.h>
+
+#include <sys/EfiSysCall.h>
+#include <sys/endian.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+
+#define CLOSE_SOCKET close
+#define SIN_ADDR(port) port.sin_addr.s_addr
+#define SIN_FAMILY(port) port.sin_family
+#define SIN_LEN(port) port.sin_len
+#define SIN_PORT(port) port.sin_port
+#define SOCKET int
+#define GET_ERRNO errno
+#define RX_TIMEOUT_ERROR ETIMEDOUT
+
+#endif // BUILD_FOR_WINDOWS
+
+#include <stdio.h>
+
+//------------------------------------------------------------------------------
+// Constants
+//------------------------------------------------------------------------------
+
+#define OOB_RX_PORT 12344
+
+//------------------------------------------------------------------------------
+// API
+//------------------------------------------------------------------------------
+
+/**
+ Run the OOB receive application
+
+ @param [in] ArgC Argument count
+ @param [in] ArgV Argument value array
+
+ @retval 0 Successfully operation
+ **/
+
+int
+OobRx (
+ IN int ArgC,
+ IN char **ArgV
+ );
+
+//------------------------------------------------------------------------------
+
+#endif // _OOB_RX_H_
diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/OobRx/OobRx.inf b/uefi/linaro-edk2/AppPkg/Applications/Sockets/OobRx/OobRx.inf
new file mode 100644
index 0000000..17a4935
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/OobRx/OobRx.inf
@@ -0,0 +1,57 @@
+## @file
+# OobRx Application
+#
+# Copyright (c) 2011-2012, Intel Corporation
+# All rights reserved. This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = OobRx
+ FILE_GUID = 79DED328-7FCE-4909-9AFD-D66176AF97A6
+ MODULE_TYPE = UEFI_APPLICATION
+ VERSION_STRING = 1.0
+ ENTRY_POINT = ShellCEntryLib
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF EBC
+#
+
+[Sources]
+ Main.c
+ OobRx.c
+
+
+[Packages]
+ MdePkg/MdePkg.dec
+ ShellPkg/ShellPkg.dec
+ StdLib/StdLib.dec
+
+
+[LibraryClasses]
+ BaseMemoryLib
+ BsdSocketLib
+ DebugLib
+ EfiSocketLib
+ LibC
+ LibMath
+ ShellCEntryLib
+ UefiBootServicesTableLib
+ UefiLib
+# UseSocketDxe
+
+[BuildOptions]
+ INTEL:*_*_*_CC_FLAGS = /Qdiag-disable:181,186
+ MSFT:*_*_*_CC_FLAGS = /Od
+ GCC:*_*_*_CC_FLAGS = -O0 -Wno-unused-variable
+
diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/OobRx/Windows/OobRx.sln b/uefi/linaro-edk2/AppPkg/Applications/Sockets/OobRx/Windows/OobRx.sln
new file mode 100644
index 0000000..f9c7825
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/OobRx/Windows/OobRx.sln
@@ -0,0 +1,20 @@
+
+Microsoft Visual Studio Solution File, Format Version 9.00
+# Visual Studio 2005
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "OobRx", "OobRx.vcproj", "{FA34A77A-5034-4065-B4BD-B74984DEB2F7}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Win32 = Debug|Win32
+ Release|Win32 = Release|Win32
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {FA34A77A-5034-4065-B4BD-B74984DEB2F7}.Debug|Win32.ActiveCfg = Debug|Win32
+ {FA34A77A-5034-4065-B4BD-B74984DEB2F7}.Debug|Win32.Build.0 = Debug|Win32
+ {FA34A77A-5034-4065-B4BD-B74984DEB2F7}.Release|Win32.ActiveCfg = Release|Win32
+ {FA34A77A-5034-4065-B4BD-B74984DEB2F7}.Release|Win32.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/OobRx/Windows/OobRx.suo b/uefi/linaro-edk2/AppPkg/Applications/Sockets/OobRx/Windows/OobRx.suo
new file mode 100644
index 0000000..025aa47
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/OobRx/Windows/OobRx.suo
Binary files differ
diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/OobRx/Windows/OobRx.vcproj b/uefi/linaro-edk2/AppPkg/Applications/Sockets/OobRx/Windows/OobRx.vcproj
new file mode 100644
index 0000000..e5ca534
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/OobRx/Windows/OobRx.vcproj
@@ -0,0 +1,211 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="OobRx"
+ ProjectGUID="{FA34A77A-5034-4065-B4BD-B74984DEB2F7}"
+ RootNamespace="OobRx"
+ Keyword="Win32Proj"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=".."
+ PreprocessorDefinitions="BUILD_FOR_WINDOWS"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ UsePrecompiledHeader="0"
+ BrowseInformation="1"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="ws2_32.lib"
+ LinkIncremental="2"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="1"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=".."
+ PreprocessorDefinitions="BUILD_FOR_WINDOWS"
+ RuntimeLibrary="2"
+ UsePrecompiledHeader="0"
+ BrowseInformation="1"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="ws2_32.lib"
+ LinkIncremental="1"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath=".\main.c"
+ >
+ </File>
+ <File
+ RelativePath="..\OobRx.c"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ <File
+ RelativePath="..\OobRx.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+ >
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/OobRx/Windows/main.c b/uefi/linaro-edk2/AppPkg/Applications/Sockets/OobRx/Windows/main.c
new file mode 100644
index 0000000..afae5da
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/OobRx/Windows/main.c
@@ -0,0 +1,56 @@
+/** @file
+ Windows version of the OOB Receive application
+
+ Copyright (c) 2011-2012, Intel Corporation
+ All rights reserved. This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <OobRx.h>
+
+
+/**
+ Receive out-of-band messages from the remote system.
+
+ @param [in] argc The number of arguments
+ @param [in] argv The argument value array
+
+ @retval 0 The application exited normally.
+ @retval Other An error occurred.
+**/
+int
+main(
+ int argc,
+ char ** argv
+ )
+{
+ int RetVal;
+ WSADATA WsaData;
+
+ //
+ // Initialize the WinSock layer
+ //
+ RetVal = WSAStartup ( MAKEWORD ( 2, 2 ), &WsaData );
+ if ( 0 == RetVal ) {
+ //
+ // Start the application
+ //
+ RetVal = OobRx ( argc, argv );
+
+ //
+ // Done with the WinSock layer
+ //
+ WSACleanup ( );
+ }
+
+ //
+ // Return the final result
+ //
+ return RetVal;
+}
diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/OobTx/Main.c b/uefi/linaro-edk2/AppPkg/Applications/Sockets/OobTx/Main.c
new file mode 100644
index 0000000..5b6ab02
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/OobTx/Main.c
@@ -0,0 +1,44 @@
+/** @file
+ Out-of-band transmit test application
+
+ Copyright (c) 2011-2012, Intel Corporation
+ All rights reserved. This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <OobTx.h>
+
+
+/**
+ Transmit out-of-band messages to the remote system.
+
+ @param [in] Argc The number of arguments
+ @param [in] Argv The argument value array
+
+ @retval 0 The application exited normally.
+ @retval Other An error occurred.
+**/
+int
+main (
+ IN int Argc,
+ IN char **Argv
+ )
+{
+ int RetVal;
+
+ //
+ // Run the application
+ //
+ RetVal = OobTx ( Argc, Argv );
+
+ //
+ // Return the operation status
+ //
+ return RetVal;
+}
diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/OobTx/OobTx.c b/uefi/linaro-edk2/AppPkg/Applications/Sockets/OobTx/OobTx.c
new file mode 100644
index 0000000..545e5f4
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/OobTx/OobTx.c
@@ -0,0 +1,248 @@
+/** @file
+ Windows version of the OOB Transmit application
+
+ Copyright (c) 2011-2012, Intel Corporation
+ All rights reserved. This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <OobTx.h>
+
+UINT8 mBuffer[8192];
+UINT8 mOob[512];
+
+/**
+ Transmit out-of-band messages to the remote system.
+
+ @param [in] ArgC Argument count
+ @param [in] ArgV Argument value array
+
+ @retval 0 Successfully operation
+ **/
+
+int
+OobTx (
+ IN int ArgC,
+ IN char **ArgV
+ )
+{
+ UINT32 BytesSent;
+ ssize_t BytesTransmitted;
+ UINT32 Index;
+ struct sockaddr_in LocalPort;
+ UINT32 OobInLine;
+ UINT16 PortNumber;
+ UINT32 RemoteAddress[4];
+ struct sockaddr_in RemotePort;
+ int RetVal;
+ UINT32 TransmittedAfter;
+ UINT32 TransmittedBefore;
+ UINT32 TransmittedOob;
+ SOCKET s;
+
+ //
+ // Create the socket
+ //
+ s = socket ( AF_INET, SOCK_STREAM, IPPROTO_TCP );
+ if ( -1 == s ) {
+ RetVal = GET_ERRNO;
+ printf ( "ERROR - socket error, errno: %d\r\n", RetVal );
+ }
+ else {
+ //
+ // Use for/break; instead of goto
+ //
+ for ( ; ; ) {
+ //
+ // Validate the arguments
+ //
+ if (( 2 > ArgC )
+ || ( 4 != sscanf ( ArgV[1],
+ "%d.%d.%d.%d",
+ &RemoteAddress[0],
+ &RemoteAddress[1],
+ &RemoteAddress[2],
+ &RemoteAddress[3]))
+ || ( 224 < RemoteAddress[0])
+ || ( 255 < RemoteAddress[1])
+ || ( 255 < RemoteAddress[2])
+ || ( 255 < RemoteAddress[3])
+ || (( 0 == RemoteAddress[0])
+ && ( 0 == RemoteAddress[1])
+ && ( 0 == RemoteAddress[2])
+ && ( 0 == RemoteAddress[3]))) {
+ printf ( "%s <remote IP address> [optional: enables in-line OOB]\r\n", ArgV[0]);
+ RetVal = EINVAL;
+ break;
+ }
+
+ //
+ // Bind the socket to a local port
+ //
+ memset ( &LocalPort, 0, sizeof ( LocalPort ));
+ SIN_LEN ( LocalPort ) = sizeof ( LocalPort );
+ SIN_FAMILY ( LocalPort ) = AF_INET;
+ SIN_ADDR ( LocalPort ) = 0;
+ SIN_PORT ( LocalPort ) = 0;
+ RetVal = bind ( s,
+ (struct sockaddr *)&LocalPort,
+ sizeof ( LocalPort ));
+ if ( -1 == RetVal ) {
+ RetVal = GET_ERRNO;
+ printf ( "ERROR - bind error, errno: %d\r\n", RetVal );
+ break;
+ }
+
+ //
+ // Specify the remote port
+ //
+ PortNumber = OOB_RX_PORT;
+ memset ( &RemotePort, 0, sizeof ( RemotePort ));
+ SIN_LEN ( RemotePort ) = sizeof ( RemotePort );
+ SIN_FAMILY ( RemotePort ) = AF_INET;
+ SIN_ADDR ( RemotePort ) = ( RemoteAddress[3] << 24 )
+ | ( RemoteAddress[2] << 16 )
+ | ( RemoteAddress[1] << 8 )
+ | RemoteAddress[0];
+ SIN_PORT ( RemotePort ) = htons ( PortNumber );
+
+ //
+ // Connect to the remote server
+ //
+ RetVal = connect ( s, (struct sockaddr *)&RemotePort, sizeof ( RemotePort ));
+ if ( -1 == RetVal ) {
+ RetVal = GET_ERRNO;
+ printf ( "ERROR - connect error, errno: %d\r\n", RetVal );
+ break;
+ }
+
+ //
+ // Select the OOB processing
+ //
+ OobInLine = ( 2 < ArgC );
+ RetVal = setsockopt ( s,
+ SOL_SOCKET,
+ SO_OOBINLINE,
+ (char *)&OobInLine,
+ sizeof ( OobInLine ));
+ if ( -1 == RetVal ) {
+ RetVal = GET_ERRNO;
+ printf ( "ERROR - setsockopt OOBINLINE error, errno: %d\r\n", RetVal );
+ break;
+ }
+ printf ( "%s\r\n", ( 0 != OobInLine ) ? "OOB messages are in-line"
+ : "OOB messages move to the head of the queue" );
+
+ //
+ // Initialize the messages
+ //
+ memset ( &mBuffer[0], 0, sizeof ( mBuffer ));
+ memset ( &mOob[0], 0x11, sizeof ( mOob ));
+
+ //
+ // Send the data before the out-of-band message
+ //
+ TransmittedBefore = 0;
+ for ( Index = 0; TX_MSGS_BEFORE > Index; Index++ ) {
+ BytesSent = 0;
+ do {
+ BytesTransmitted = send ( s,
+ &mBuffer[BytesSent],
+ sizeof ( mBuffer ) - BytesSent,
+ 0 );
+ if ( -1 == BytesTransmitted ) {
+ RetVal = GET_ERRNO;
+ printf ( "ERROR - send before error, errno: %d\r\n", RetVal );
+ break;
+ }
+ BytesSent += (UINT32)BytesTransmitted;
+ RetVal = 0;
+ } while ( sizeof ( mBuffer ) > BytesSent );
+ if ( 0 != RetVal ) {
+ break;
+ }
+ TransmittedBefore += BytesSent;
+ }
+ if ( 0 != RetVal ) {
+ break;
+ }
+
+ //
+ // Send the out-of-band message
+ //
+ BytesSent = 0;
+ do {
+ BytesTransmitted = send ( s,
+ &mOob[BytesSent],
+ sizeof ( mOob ) - BytesSent,
+ MSG_OOB );
+ if ( -1 == BytesTransmitted ) {
+ RetVal = GET_ERRNO;
+ printf ( "ERROR - send OOB error, errno: %d\r\n", RetVal );
+ break;
+ }
+ BytesSent += (UINT32)BytesTransmitted;
+ RetVal = 0;
+ } while ( sizeof ( mOob ) > BytesSent );
+ if ( 0 != RetVal ) {
+ break;
+ }
+ TransmittedOob = BytesSent;
+
+ //
+ // Send the data after the out-of-band message
+ //
+ TransmittedAfter = 0;
+ for ( Index = 0; TX_MSGS_AFTER > Index; Index++ ) {
+ BytesSent = 0;
+ do {
+ BytesTransmitted = send ( s,
+ &mBuffer[BytesSent],
+ sizeof ( mBuffer ) - BytesSent,
+ 0 );
+ if ( -1 == BytesTransmitted ) {
+ RetVal = GET_ERRNO;
+ printf ( "ERROR - send after error, errno: %d\r\n", RetVal );
+ break;
+ }
+ BytesSent += (UINT32)BytesTransmitted;
+ RetVal = 0;
+ } while ( sizeof ( mBuffer ) > BytesSent );
+ if ( 0 != RetVal ) {
+ break;
+ }
+ TransmittedAfter += BytesSent;
+ }
+
+ //
+ // Test completed successfully
+ //
+ if ( 0 == RetVal ) {
+ printf ( "Bytes before OOB: %8d\r\n", TransmittedBefore );
+ printf ( "Out-of-band bytes: %8d\r\n", TransmittedOob );
+ printf ( "Bytes after OOB: %8d\r\n", TransmittedAfter );
+ printf ( " --------\r\n" );
+ printf ( "Total Bytes: %8d\r\n", TransmittedBefore
+ + TransmittedOob
+ + TransmittedAfter );
+ }
+ break;
+ }
+
+ //
+ // Close the socket
+ //
+ CLOSE_SOCKET ( s );
+ }
+
+ //
+ // Return the operation status
+ //
+ return RetVal;
+}
diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/OobTx/OobTx.h b/uefi/linaro-edk2/AppPkg/Applications/Sockets/OobTx/OobTx.h
new file mode 100644
index 0000000..e042a13
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/OobTx/OobTx.h
@@ -0,0 +1,98 @@
+/** @file
+ Definitions for the OOB Transmit application
+
+ Copyright (c) 2011-2012, Intel Corporation
+ All rights reserved. This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef _OOB_TX_H_
+#define _OOB_TX_H_
+
+//------------------------------------------------------------------------------
+// Include Files
+//------------------------------------------------------------------------------
+
+#ifdef BUILD_FOR_WINDOWS
+//
+// Build for Windows environment
+//
+
+#include <winsock2.h>
+
+#define CHAR8 char
+#define CLOSE_SOCKET closesocket
+#define EINVAL 22 // Invalid argument
+#define GET_ERRNO WSAGetLastError ( )
+#define SIN_ADDR(port) port.sin_addr.S_un.S_addr
+#define SIN_FAMILY(port) port.sin_family
+#define SIN_LEN(port) port.sin_family
+#define SIN_PORT(port) port.sin_port
+#define socklen_t int
+#define ssize_t int
+
+#else // BUILD_FOR_WINDOWS
+//
+// Build for EFI environment
+//
+
+#include <Uefi.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <netinet/in.h>
+
+#include <sys/EfiSysCall.h>
+#include <sys/endian.h>
+#include <sys/socket.h>
+
+#define CLOSE_SOCKET close
+#define GET_ERRNO errno
+#define SIN_ADDR(port) port.sin_addr.s_addr
+#define SIN_FAMILY(port) port.sin_family
+#define SIN_LEN(port) port.sin_len
+#define SIN_PORT(port) port.sin_port
+#define SOCKET int
+
+#endif // BUILD_FOR_WINDOWS
+
+#include <stdio.h>
+
+//------------------------------------------------------------------------------
+// Constants
+//------------------------------------------------------------------------------
+
+#define OOB_RX_PORT 12344
+
+#define TX_MSGS_BEFORE 32
+#define TX_MSGS_AFTER 8
+
+//------------------------------------------------------------------------------
+// API
+//------------------------------------------------------------------------------
+
+/**
+ Transmit out-of-band messages to the remote system.
+
+ @param [in] ArgC Argument count
+ @param [in] ArgV Argument value array
+
+ @retval 0 Successfully operation
+ **/
+
+int
+OobTx (
+ IN int ArgC,
+ IN char **ArgV
+ );
+
+//------------------------------------------------------------------------------
+
+#endif // _OOB_TX_H_
diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/OobTx/OobTx.inf b/uefi/linaro-edk2/AppPkg/Applications/Sockets/OobTx/OobTx.inf
new file mode 100644
index 0000000..f12e389
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/OobTx/OobTx.inf
@@ -0,0 +1,57 @@
+## @file
+# OobTx Application
+#
+# Copyright (c) 2011-2012, Intel Corporation
+# All rights reserved. This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = OobTx
+ FILE_GUID = EB740091-A494-44d7-8D96-C192F95A6394
+ MODULE_TYPE = UEFI_APPLICATION
+ VERSION_STRING = 1.0
+ ENTRY_POINT = ShellCEntryLib
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF EBC
+#
+
+[Sources]
+ Main.c
+ OobTx.c
+
+
+[Packages]
+ MdePkg/MdePkg.dec
+ ShellPkg/ShellPkg.dec
+ StdLib/StdLib.dec
+
+
+[LibraryClasses]
+ BaseMemoryLib
+ BsdSocketLib
+ DebugLib
+ EfiSocketLib
+ LibC
+ LibMath
+ ShellCEntryLib
+ UefiBootServicesTableLib
+ UefiLib
+# UseSocketDxe
+
+[BuildOptions]
+ INTEL:*_*_*_CC_FLAGS = /Qdiag-disable:181,186
+ MSFT:*_*_*_CC_FLAGS = /Od
+ GCC:*_*_*_CC_FLAGS = -O0 -Wno-unused-variable
+
diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/OobTx/Windows/OobTx.sln b/uefi/linaro-edk2/AppPkg/Applications/Sockets/OobTx/Windows/OobTx.sln
new file mode 100644
index 0000000..e16b5fd
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/OobTx/Windows/OobTx.sln
@@ -0,0 +1,20 @@
+
+Microsoft Visual Studio Solution File, Format Version 9.00
+# Visual Studio 2005
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "OobTx", "OobTx.vcproj", "{C5B91ED2-C2BA-4EE7-A789-F6621CE601B9}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Win32 = Debug|Win32
+ Release|Win32 = Release|Win32
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {C5B91ED2-C2BA-4EE7-A789-F6621CE601B9}.Debug|Win32.ActiveCfg = Debug|Win32
+ {C5B91ED2-C2BA-4EE7-A789-F6621CE601B9}.Debug|Win32.Build.0 = Debug|Win32
+ {C5B91ED2-C2BA-4EE7-A789-F6621CE601B9}.Release|Win32.ActiveCfg = Release|Win32
+ {C5B91ED2-C2BA-4EE7-A789-F6621CE601B9}.Release|Win32.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/OobTx/Windows/OobTx.suo b/uefi/linaro-edk2/AppPkg/Applications/Sockets/OobTx/Windows/OobTx.suo
new file mode 100644
index 0000000..0ded407
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/OobTx/Windows/OobTx.suo
Binary files differ
diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/OobTx/Windows/OobTx.vcproj b/uefi/linaro-edk2/AppPkg/Applications/Sockets/OobTx/Windows/OobTx.vcproj
new file mode 100644
index 0000000..d53149c
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/OobTx/Windows/OobTx.vcproj
@@ -0,0 +1,211 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="OobTx"
+ ProjectGUID="{C5B91ED2-C2BA-4EE7-A789-F6621CE601B9}"
+ RootNamespace="OobTx"
+ Keyword="Win32Proj"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=".."
+ PreprocessorDefinitions="BUILD_FOR_WINDOWS; _CRT_SECURE_NO_DEPRECATE"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ UsePrecompiledHeader="0"
+ BrowseInformation="1"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="ws2_32.lib"
+ LinkIncremental="2"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="1"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=".."
+ PreprocessorDefinitions="BUILD_FOR_WINDOWS; _CRT_SECURE_NO_DEPRECATE"
+ RuntimeLibrary="2"
+ UsePrecompiledHeader="0"
+ BrowseInformation="1"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="ws2_32.lib"
+ LinkIncremental="1"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath=".\main.c"
+ >
+ </File>
+ <File
+ RelativePath="..\OobTx.c"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ <File
+ RelativePath="..\OobTx.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+ >
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/OobTx/Windows/main.c b/uefi/linaro-edk2/AppPkg/Applications/Sockets/OobTx/Windows/main.c
new file mode 100644
index 0000000..dd0f3a2
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/OobTx/Windows/main.c
@@ -0,0 +1,56 @@
+/** @file
+ Windows version of the OOB Transmit application
+
+ Copyright (c) 2011-2012, Intel Corporation
+ All rights reserved. This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <OobTx.h>
+
+
+/**
+ Transmit out-of-band messages to the remote system.
+
+ @param [in] Argc The number of arguments
+ @param [in] Argv The argument value array
+
+ @retval 0 The application exited normally.
+ @retval Other An error occurred.
+**/
+int
+main(
+ int argc,
+ char ** argv
+ )
+{
+ int RetVal;
+ WSADATA WsaData;
+
+ //
+ // Initialize the WinSock layer
+ //
+ RetVal = WSAStartup ( MAKEWORD ( 2, 2 ), &WsaData );
+ if ( 0 == RetVal ) {
+ //
+ // Start the application
+ //
+ RetVal = OobTx ( argc, argv );
+
+ //
+ // Done with the WinSock layer
+ //
+ WSACleanup ( );
+ }
+
+ //
+ // Return the final result
+ //
+ return RetVal;
+}
diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/RawIp4Rx/Main.c b/uefi/linaro-edk2/AppPkg/Applications/Sockets/RawIp4Rx/Main.c
new file mode 100644
index 0000000..0857b23
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/RawIp4Rx/Main.c
@@ -0,0 +1,44 @@
+/** @file
+ Raw IP4 receive test application
+
+ Copyright (c) 2011-2012, Intel Corporation
+ All rights reserved. This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "RawIp4Rx.h"
+
+
+/**
+ Receive raw datagrams from a remote system.
+
+ @param [in] Argc The number of arguments
+ @param [in] Argv The argument value array
+
+ @retval 0 The application exited normally.
+ @retval Other An error occurred.
+**/
+int
+main (
+ IN int Argc,
+ IN char **Argv
+ )
+{
+ int RetVal;
+
+ //
+ // Run the application
+ //
+ RetVal = RawIp4Rx ( Argc, Argv );
+
+ //
+ // Return the operation status
+ //
+ return RetVal;
+}
diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/RawIp4Rx/RawIp4Rx.c b/uefi/linaro-edk2/AppPkg/Applications/Sockets/RawIp4Rx/RawIp4Rx.c
new file mode 100644
index 0000000..bce4578
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/RawIp4Rx/RawIp4Rx.c
@@ -0,0 +1,188 @@
+/** @file
+ Raw IP4 receive application
+
+ Copyright (c) 2011-2012, Intel Corporation
+ All rights reserved. This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "RawIp4Rx.h"
+
+UINT8 mBuffer[65536];
+
+
+/**
+ Run the raw IP4 receive application
+
+ @param [in] ArgC Argument count
+ @param [in] ArgV Argument value array
+
+ @retval 0 Successfully operation
+ **/
+int
+RawIp4Rx (
+ IN int ArgC,
+ IN char **ArgV
+ )
+{
+ ssize_t BytesReceived;
+ struct sockaddr_in LocalPort;
+ socklen_t LocalPortLength;
+ struct sockaddr_in RemotePort;
+ socklen_t RemotePortLength;
+ int RetVal;
+ SOCKET s;
+ UINT64 TotalBytesReceived;
+
+ //
+ // Create the socket
+ //
+ s = socket ( AF_INET, SOCK_RAW, RAW_PROTOCOL );
+ if ( -1 == s ) {
+ RetVal = GET_ERRNO;
+ printf ( "ERROR - socket error, errno: %d\r\n", RetVal );
+ }
+ else {
+ //
+ // Use for/break; instead of goto
+ //
+ for ( ; ; ) {
+ //
+ // Bind the socket to a known port
+ //
+ memset ( &LocalPort, 0, sizeof ( LocalPort ));
+ SIN_LEN ( LocalPort ) = sizeof ( LocalPort );
+ SIN_FAMILY ( LocalPort ) = AF_INET;
+ SIN_ADDR ( LocalPort ) = 0;
+ SIN_PORT ( LocalPort ) = 0;
+ RetVal = bind ( s,
+ (struct sockaddr *)&LocalPort,
+ sizeof ( LocalPort ));
+ if ( -1 == RetVal ) {
+ RetVal = GET_ERRNO;
+ printf ( "ERROR - bind error, errno: %d\r\n", RetVal );
+ break;
+ }
+
+ //
+ // Display the local address and protocol
+ //
+ LocalPortLength = sizeof ( LocalPort );
+ RetVal = getsockname ( s, (struct sockaddr *)&LocalPort, &LocalPortLength );
+ if ( 0 != RetVal ) {
+ RetVal = GET_ERRNO;
+ printf ( "ERROR - getsockname error, errno: %d\r\n", RetVal );
+ break;
+ }
+ printf ( "Local Address: %d.%d.%d.%d, Protocol: %d\r\n",
+ (UINT8)SIN_ADDR ( LocalPort ),
+ (UINT8)( SIN_ADDR ( LocalPort ) >> 8 ),
+ (UINT8)( SIN_ADDR ( LocalPort ) >> 16 ),
+ (UINT8)( SIN_ADDR ( LocalPort ) >> 24 ),
+ RAW_PROTOCOL );
+
+ //
+ // Use for/break instead of goto
+ //
+ TotalBytesReceived = 0;
+ for ( ; ; ) {
+ //
+ // Receive data from the remote system
+ //
+ do {
+ //
+ // Attempt to receive a packet
+ //
+ RemotePortLength = sizeof ( RemotePort );
+ BytesReceived = recvfrom ( s,
+ &mBuffer[0],
+ sizeof ( mBuffer ),
+ 0,
+ (struct sockaddr *)&RemotePort,
+ &RemotePortLength );
+ RetVal = (UINT32)BytesReceived;
+ if ( 0 < BytesReceived ) {
+ //
+ // Display the received data
+ //
+ printf ( "%4d bytes received from %d.%d.%d.%d:%d\r\n"
+ "%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\r\n"
+ "%02x %02x %02x %02x\r\n",
+ (UINT32)BytesReceived,
+ (UINT8)SIN_ADDR ( RemotePort ),
+ (UINT8)( SIN_ADDR ( RemotePort ) >> 8 ),
+ (UINT8)( SIN_ADDR ( RemotePort ) >> 16 ),
+ (UINT8)( SIN_ADDR ( RemotePort ) >> 24 ),
+ SIN_PORT ( RemotePort ),
+ mBuffer[0],
+ mBuffer[1],
+ mBuffer[2],
+ mBuffer[3],
+ mBuffer[4],
+ mBuffer[5],
+ mBuffer[6],
+ mBuffer[7],
+ mBuffer[8],
+ mBuffer[9],
+ mBuffer[10],
+ mBuffer[11],
+ mBuffer[12],
+ mBuffer[13],
+ mBuffer[14],
+ mBuffer[15],
+ mBuffer[16],
+ mBuffer[17],
+ mBuffer[18],
+ mBuffer[19]);
+ TotalBytesReceived += BytesReceived;
+
+ //
+ // All done when the correct packet is received
+ //
+ if ( mBuffer[9] == RAW_PROTOCOL ) {
+ break;
+ }
+ }
+ else if ( -1 == BytesReceived ) {
+ //
+ // Check for a timeout
+ //
+ RetVal = GET_ERRNO;
+ printf ( "ERROR - recv error, errno: %d\r\n", RetVal );
+ break;
+ }
+ } while ( 0 != RetVal );
+
+ //
+ // Display the bytes received
+ //
+ if ( 0 == RetVal ) {
+ printf ( "Total Bytes Received: %Ld\r\n", TotalBytesReceived );
+ }
+
+ //
+ // Test complete
+ //
+ break;
+ }
+ break;
+ }
+
+ //
+ // Close the socket
+ //
+ CLOSE_SOCKET ( s );
+ printf ( "Socket closed\r\n" );
+ }
+
+ //
+ // Return the operation status
+ //
+ return RetVal;
+}
diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/RawIp4Rx/RawIp4Rx.h b/uefi/linaro-edk2/AppPkg/Applications/Sockets/RawIp4Rx/RawIp4Rx.h
new file mode 100644
index 0000000..ae8daac
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/RawIp4Rx/RawIp4Rx.h
@@ -0,0 +1,99 @@
+/** @file
+ Definitions for the raw IP4 receive application
+
+ Copyright (c) 2011-2012, Intel Corporation
+ All rights reserved. This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef _RAW_IP4_RX_H_
+#define _RAW_IP4_RX_H_
+
+//------------------------------------------------------------------------------
+// Include Files
+//------------------------------------------------------------------------------
+
+#ifdef BUILD_FOR_WINDOWS
+//
+// Build for Windows environment
+//
+
+#include <winsock2.h>
+
+#define CLOSE_SOCKET closesocket
+#define SIN_ADDR(port) port.sin_addr.S_un.S_addr
+#define SIN_FAMILY(port) port.sin_family
+#define SIN_LEN(port) port.sin_family
+#define SIN_PORT(port) port.sin_port
+#define GET_ERRNO WSAGetLastError ( )
+
+#define ssize_t int
+#define socklen_t int
+
+#else // BUILD_FOR_WINDOWS
+//
+// Build for EFI environment
+//
+
+#include <Uefi.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <netinet/in.h>
+
+#include <sys/EfiSysCall.h>
+#include <sys/endian.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+
+#define CLOSE_SOCKET close
+#define SIN_ADDR(port) port.sin_addr.s_addr
+#define SIN_FAMILY(port) port.sin_family
+#define SIN_LEN(port) port.sin_len
+#define SIN_PORT(port) port.sin_port
+#define SOCKET int
+#define GET_ERRNO errno
+
+#endif // BUILD_FOR_WINDOWS
+
+#include <stdio.h>
+
+//------------------------------------------------------------------------------
+// Constants
+//------------------------------------------------------------------------------
+
+//
+// See http://www.iana.org/assignments/protocol-numbers/protocol-numbers.xml
+// and http://tools.ietf.org/html/rfc3692
+//
+#define RAW_PROTOCOL 253
+
+//------------------------------------------------------------------------------
+// API
+//------------------------------------------------------------------------------
+
+/**
+ Run the raw IP4 receive application
+
+ @param [in] ArgC Argument count
+ @param [in] ArgV Argument value array
+
+ @retval 0 Successfully operation
+ **/
+
+int
+RawIp4Rx (
+ IN int ArgC,
+ IN char **ArgV
+ );
+
+//------------------------------------------------------------------------------
+
+#endif // _RAW_IP4_RX_H_
diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/RawIp4Rx/RawIp4Rx.inf b/uefi/linaro-edk2/AppPkg/Applications/Sockets/RawIp4Rx/RawIp4Rx.inf
new file mode 100644
index 0000000..232f050
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/RawIp4Rx/RawIp4Rx.inf
@@ -0,0 +1,57 @@
+## @file
+# RawIp4 Application
+#
+# Copyright (c) 2011-2012, Intel Corporation
+# All rights reserved. This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = RawIp4Rx
+ FILE_GUID = 8D7AE6A9-B490-45e1-8795-C2BEAADC3814
+ MODULE_TYPE = UEFI_APPLICATION
+ VERSION_STRING = 1.0
+ ENTRY_POINT = ShellCEntryLib
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF EBC
+#
+
+[Sources]
+ Main.c
+ RawIp4Rx.c
+
+
+[Packages]
+ MdePkg/MdePkg.dec
+ ShellPkg/ShellPkg.dec
+ StdLib/StdLib.dec
+
+
+[LibraryClasses]
+ BaseMemoryLib
+ BsdSocketLib
+ DebugLib
+ EfiSocketLib
+ LibC
+ LibMath
+ ShellCEntryLib
+ UefiBootServicesTableLib
+ UefiLib
+# UseSocketDxe
+
+[BuildOptions]
+ INTEL:*_*_*_CC_FLAGS = /Qdiag-disable:181,186
+ MSFT:*_*_*_CC_FLAGS = /Od
+ GCC:*_*_*_CC_FLAGS = -O0 -Wno-unused-variable
+
diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/RawIp4Rx/Windows/RawIp4Rx.sln b/uefi/linaro-edk2/AppPkg/Applications/Sockets/RawIp4Rx/Windows/RawIp4Rx.sln
new file mode 100644
index 0000000..5c2b797
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/RawIp4Rx/Windows/RawIp4Rx.sln
@@ -0,0 +1,20 @@
+
+Microsoft Visual Studio Solution File, Format Version 9.00
+# Visual Studio 2005
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RawIp4Rx", "RawIp4Rx.vcproj", "{FAD3909F-E05E-4A2A-9681-7C474EAC5025}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Win32 = Debug|Win32
+ Release|Win32 = Release|Win32
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {FAD3909F-E05E-4A2A-9681-7C474EAC5025}.Debug|Win32.ActiveCfg = Debug|Win32
+ {FAD3909F-E05E-4A2A-9681-7C474EAC5025}.Debug|Win32.Build.0 = Debug|Win32
+ {FAD3909F-E05E-4A2A-9681-7C474EAC5025}.Release|Win32.ActiveCfg = Release|Win32
+ {FAD3909F-E05E-4A2A-9681-7C474EAC5025}.Release|Win32.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/RawIp4Rx/Windows/RawIp4Rx.vcproj b/uefi/linaro-edk2/AppPkg/Applications/Sockets/RawIp4Rx/Windows/RawIp4Rx.vcproj
new file mode 100644
index 0000000..f0f61c4
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/RawIp4Rx/Windows/RawIp4Rx.vcproj
@@ -0,0 +1,211 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="RawIp4Rx"
+ ProjectGUID="{FAD3909F-E05E-4A2A-9681-7C474EAC5025}"
+ RootNamespace="RawIp4Rx"
+ Keyword="Win32Proj"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=".."
+ PreprocessorDefinitions="BUILD_FOR_WINDOWS"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ UsePrecompiledHeader="0"
+ BrowseInformation="1"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="ws2_32.lib"
+ LinkIncremental="2"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="1"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=".."
+ PreprocessorDefinitions="BUILD_FOR_WINDOWS"
+ RuntimeLibrary="2"
+ UsePrecompiledHeader="0"
+ BrowseInformation="1"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="ws2_32.lib"
+ LinkIncremental="1"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath=".\main.c"
+ >
+ </File>
+ <File
+ RelativePath="..\RawIp4Rx.c"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ <File
+ RelativePath="..\RawIp4Rx.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+ >
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/RawIp4Rx/Windows/main.c b/uefi/linaro-edk2/AppPkg/Applications/Sockets/RawIp4Rx/Windows/main.c
new file mode 100644
index 0000000..530c2d6
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/RawIp4Rx/Windows/main.c
@@ -0,0 +1,61 @@
+/** @file
+ Windows version of the raw IP4 receive application
+
+ Copyright (c) 2011-2012, Intel Corporation
+ All rights reserved. This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <RawIp4Rx.h>
+
+
+/**
+ Receive raw IP4 packets from a remote system.
+
+ Please note that this program must be run with administrator privileges!
+
+ @param [in] argc The number of arguments
+ @param [in] argv The argument value array
+
+ @retval 0 The application exited normally.
+ @retval Other An error occurred.
+**/
+int
+main(
+ int argc,
+ char ** argv
+ )
+{
+ int RetVal;
+ WSADATA WsaData;
+
+ //
+ // Initialize the WinSock layer
+ //
+ RetVal = WSAStartup ( MAKEWORD ( 2, 2 ), &WsaData );
+ if ( 0 == RetVal ) {
+ //
+ // Start the application
+ //
+ RetVal = RawIp4Rx ( argc, argv );
+ if ( WSAEACCES == RetVal ) {
+ printf ( "Requires administrator privileges to run!\r\n" );
+ }
+
+ //
+ // Done with the WinSock layer
+ //
+ WSACleanup ( );
+ }
+
+ //
+ // Return the final result
+ //
+ return RetVal;
+}
diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/RawIp4Tx/Main.c b/uefi/linaro-edk2/AppPkg/Applications/Sockets/RawIp4Tx/Main.c
new file mode 100644
index 0000000..451193a
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/RawIp4Tx/Main.c
@@ -0,0 +1,44 @@
+/** @file
+ Raw IP4 transmit test application
+
+ Copyright (c) 2011-2012, Intel Corporation
+ All rights reserved. This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "RawIp4Tx.h"
+
+
+/**
+ Transmit raw IP4 packets to the remote system.
+
+ @param [in] Argc The number of arguments
+ @param [in] Argv The argument value array
+
+ @retval 0 The application exited normally.
+ @retval Other An error occurred.
+**/
+int
+main (
+ IN int Argc,
+ IN char **Argv
+ )
+{
+ int RetVal;
+
+ //
+ // Run the application
+ //
+ RetVal = RawIp4Tx ( Argc, Argv );
+
+ //
+ // Return the operation status
+ //
+ return RetVal;
+}
diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/RawIp4Tx/RawIp4Tx.c b/uefi/linaro-edk2/AppPkg/Applications/Sockets/RawIp4Tx/RawIp4Tx.c
new file mode 100644
index 0000000..f6efbe1
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/RawIp4Tx/RawIp4Tx.c
@@ -0,0 +1,157 @@
+/** @file
+ Raw IP4 transmit application
+
+ Copyright (c) 2011-2012, Intel Corporation
+ All rights reserved. This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "RawIp4Tx.h"
+
+UINT8 mBuffer[1024];
+
+/**
+ Transmit raw IP4 packets to the remote system.
+
+ @param [in] ArgC Argument count
+ @param [in] ArgV Argument value array
+
+ @retval 0 Successfully operation
+ **/
+
+int
+RawIp4Tx (
+ IN int ArgC,
+ IN char **ArgV
+ )
+{
+ UINT32 BytesSent;
+ ssize_t BytesTransmitted;
+ struct sockaddr_in LocalPort;
+ UINT32 RemoteAddress[4];
+ struct sockaddr_in RemotePort;
+ int RetVal;
+ UINT32 TotalSent;
+ SOCKET s;
+
+ //
+ // Create the socket
+ //
+ s = socket ( AF_INET, SOCK_RAW, RAW_PROTOCOL );
+ if ( -1 == s ) {
+ RetVal = GET_ERRNO;
+ printf ( "ERROR - socket error, errno: %d\r\n", RetVal );
+ }
+ else {
+ //
+ // Use for/break; instead of goto
+ //
+ for ( ; ; ) {
+ //
+ // Validate the arguments
+ //
+ if (( 2 > ArgC )
+ || ( 4 != sscanf ( ArgV[1],
+ "%d.%d.%d.%d",
+ &RemoteAddress[0],
+ &RemoteAddress[1],
+ &RemoteAddress[2],
+ &RemoteAddress[3]))
+ || ( 224 < RemoteAddress[0])
+ || ( 255 < RemoteAddress[1])
+ || ( 255 < RemoteAddress[2])
+ || ( 255 < RemoteAddress[3])
+ || (( 0 == RemoteAddress[0])
+ && ( 0 == RemoteAddress[1])
+ && ( 0 == RemoteAddress[2])
+ && ( 0 == RemoteAddress[3]))) {
+ printf ( "%s <remote IP address>\r\n", ArgV[0]);
+ RetVal = EINVAL;
+ break;
+ }
+
+ //
+ // Bind the socket to a local port
+ //
+ memset ( &LocalPort, 0, sizeof ( LocalPort ));
+ SIN_LEN ( LocalPort ) = sizeof ( LocalPort );
+ SIN_FAMILY ( LocalPort ) = AF_INET;
+ SIN_ADDR ( LocalPort ) = 0;
+ SIN_PORT ( LocalPort ) = 0;
+ RetVal = bind ( s,
+ (struct sockaddr *)&LocalPort,
+ sizeof ( LocalPort ));
+ if ( -1 == RetVal ) {
+ RetVal = GET_ERRNO;
+ printf ( "ERROR - bind error, errno: %d\r\n", RetVal );
+ break;
+ }
+
+ //
+ // Specify the remote port
+ //
+ memset ( &RemotePort, 0, sizeof ( RemotePort ));
+ SIN_LEN ( RemotePort ) = sizeof ( RemotePort );
+ SIN_FAMILY ( RemotePort ) = AF_INET;
+ SIN_ADDR ( RemotePort ) = ( RemoteAddress[3] << 24 )
+ | ( RemoteAddress[2] << 16 )
+ | ( RemoteAddress[1] << 8 )
+ | RemoteAddress[0];
+ SIN_PORT ( RemotePort ) = 0;
+
+ //
+ // Initialize the messages
+ //
+ memset ( &mBuffer[0], 0, sizeof ( mBuffer ));
+
+ //
+ // Send the data before the out-of-band message
+ //
+ TotalSent = 0;
+ BytesSent = 0;
+ do {
+ BytesTransmitted = sendto ( s,
+ &mBuffer[BytesSent],
+ sizeof ( mBuffer ) - BytesSent,
+ 0,
+ (struct sockaddr *)&RemotePort,
+ sizeof ( RemotePort ));
+ if ( -1 == BytesTransmitted ) {
+ RetVal = GET_ERRNO;
+ printf ( "ERROR - send before error, errno: %d\r\n", RetVal );
+ break;
+ }
+ BytesSent += (UINT32)BytesTransmitted;
+ RetVal = 0;
+ } while ( sizeof ( mBuffer ) > BytesSent );
+ if ( 0 != RetVal ) {
+ break;
+ }
+ TotalSent += BytesSent;
+
+ //
+ // Test completed successfully
+ //
+ if ( 0 == RetVal ) {
+ printf ( "Bytes sent: %8d\r\n", TotalSent );
+ }
+ break;
+ }
+
+ //
+ // Close the socket
+ //
+ CLOSE_SOCKET ( s );
+ }
+
+ //
+ // Return the operation status
+ //
+ return RetVal;
+}
diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/RawIp4Tx/RawIp4Tx.h b/uefi/linaro-edk2/AppPkg/Applications/Sockets/RawIp4Tx/RawIp4Tx.h
new file mode 100644
index 0000000..2fe2839
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/RawIp4Tx/RawIp4Tx.h
@@ -0,0 +1,99 @@
+/** @file
+ Definitions for the raw IP4 transmit application
+
+ Copyright (c) 2011-2012, Intel Corporation
+ All rights reserved. This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef _RAW_IP4_TX_H_
+#define _RAW_IP4_TX_H_
+
+//------------------------------------------------------------------------------
+// Include Files
+//------------------------------------------------------------------------------
+
+#ifdef BUILD_FOR_WINDOWS
+//
+// Build for Windows environment
+//
+
+#include <winsock2.h>
+
+#define CHAR8 char
+#define CLOSE_SOCKET closesocket
+#define EINVAL 22 // Invalid argument
+#define GET_ERRNO WSAGetLastError ( )
+#define SIN_ADDR(port) port.sin_addr.S_un.S_addr
+#define SIN_FAMILY(port) port.sin_family
+#define SIN_LEN(port) port.sin_family
+#define SIN_PORT(port) port.sin_port
+#define socklen_t int
+#define ssize_t int
+
+#else // BUILD_FOR_WINDOWS
+//
+// Build for EFI environment
+//
+
+#include <Uefi.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <netinet/in.h>
+
+#include <sys/EfiSysCall.h>
+#include <sys/endian.h>
+#include <sys/socket.h>
+
+#define CLOSE_SOCKET close
+#define GET_ERRNO errno
+#define SIN_ADDR(port) port.sin_addr.s_addr
+#define SIN_FAMILY(port) port.sin_family
+#define SIN_LEN(port) port.sin_len
+#define SIN_PORT(port) port.sin_port
+#define SOCKET int
+
+#endif // BUILD_FOR_WINDOWS
+
+#include <stdio.h>
+
+//------------------------------------------------------------------------------
+// Constants
+//------------------------------------------------------------------------------
+
+//
+// See http://www.iana.org/assignments/protocol-numbers/protocol-numbers.xml
+// and http://tools.ietf.org/html/rfc3692
+//
+#define RAW_PROTOCOL 253
+
+//------------------------------------------------------------------------------
+// API
+//------------------------------------------------------------------------------
+
+/**
+ Transmit raw IP4 packets to the remote system.
+
+ @param [in] ArgC Argument count
+ @param [in] ArgV Argument value array
+
+ @retval 0 Successfully operation
+ **/
+
+int
+RawIp4Tx (
+ IN int ArgC,
+ IN char **ArgV
+ );
+
+//------------------------------------------------------------------------------
+
+#endif // _RAW_IP4_TX_H_
\ No newline at end of file
diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/RawIp4Tx/RawIp4Tx.inf b/uefi/linaro-edk2/AppPkg/Applications/Sockets/RawIp4Tx/RawIp4Tx.inf
new file mode 100644
index 0000000..32d5182
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/RawIp4Tx/RawIp4Tx.inf
@@ -0,0 +1,57 @@
+## @file
+# RawIp4Tx Application
+#
+# Copyright (c) 2011-2012, Intel Corporation
+# All rights reserved. This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = RawIp4Tx
+ FILE_GUID = 3DFE0FAB-70C7-4b53-9855-985F14DB2DDA
+ MODULE_TYPE = UEFI_APPLICATION
+ VERSION_STRING = 1.0
+ ENTRY_POINT = ShellCEntryLib
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF EBC
+#
+
+[Sources]
+ Main.c
+ RawIp4Tx.c
+
+
+[Packages]
+ MdePkg/MdePkg.dec
+ ShellPkg/ShellPkg.dec
+ StdLib/StdLib.dec
+
+
+[LibraryClasses]
+ BaseMemoryLib
+ BsdSocketLib
+ DebugLib
+ EfiSocketLib
+ LibC
+ LibMath
+ ShellCEntryLib
+ UefiBootServicesTableLib
+ UefiLib
+# UseSocketDxe
+
+[BuildOptions]
+ INTEL:*_*_*_CC_FLAGS = /Qdiag-disable:181,186
+ MSFT:*_*_*_CC_FLAGS = /Od
+ GCC:*_*_*_CC_FLAGS = -O0 -Wno-unused-variable
+
diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/RawIp4Tx/Windows/RawIp4Tx.sln b/uefi/linaro-edk2/AppPkg/Applications/Sockets/RawIp4Tx/Windows/RawIp4Tx.sln
new file mode 100644
index 0000000..d5a5d37
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/RawIp4Tx/Windows/RawIp4Tx.sln
@@ -0,0 +1,20 @@
+
+Microsoft Visual Studio Solution File, Format Version 9.00
+# Visual Studio 2005
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RawIp4Tx", "RawIp4Tx.vcproj", "{11018D35-F3E3-40F4-9213-7D277AF01A17}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Win32 = Debug|Win32
+ Release|Win32 = Release|Win32
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {11018D35-F3E3-40F4-9213-7D277AF01A17}.Debug|Win32.ActiveCfg = Debug|Win32
+ {11018D35-F3E3-40F4-9213-7D277AF01A17}.Debug|Win32.Build.0 = Debug|Win32
+ {11018D35-F3E3-40F4-9213-7D277AF01A17}.Release|Win32.ActiveCfg = Release|Win32
+ {11018D35-F3E3-40F4-9213-7D277AF01A17}.Release|Win32.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/RawIp4Tx/Windows/RawIp4Tx.vcproj b/uefi/linaro-edk2/AppPkg/Applications/Sockets/RawIp4Tx/Windows/RawIp4Tx.vcproj
new file mode 100644
index 0000000..87d3d5d
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/RawIp4Tx/Windows/RawIp4Tx.vcproj
@@ -0,0 +1,211 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="RawIp4Tx"
+ ProjectGUID="{11018D35-F3E3-40F4-9213-7D277AF01A17}"
+ RootNamespace="RawIp4Tx"
+ Keyword="Win32Proj"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=".."
+ PreprocessorDefinitions="BUILD_FOR_WINDOWS; _CRT_SECURE_NO_DEPRECATE"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ UsePrecompiledHeader="0"
+ BrowseInformation="1"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="WS2_32.lib"
+ LinkIncremental="2"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="1"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=".."
+ PreprocessorDefinitions="BUILD_FOR_WINDOWS; _CRT_SECURE_NO_DEPRECATE"
+ RuntimeLibrary="2"
+ UsePrecompiledHeader="0"
+ BrowseInformation="1"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="WS2_32.lib"
+ LinkIncremental="1"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath=".\main.c"
+ >
+ </File>
+ <File
+ RelativePath="..\RawIp4Tx.c"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ <File
+ RelativePath="..\RawIp4Tx.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+ >
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/RawIp4Tx/Windows/main.c b/uefi/linaro-edk2/AppPkg/Applications/Sockets/RawIp4Tx/Windows/main.c
new file mode 100644
index 0000000..441a951
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/RawIp4Tx/Windows/main.c
@@ -0,0 +1,62 @@
+/** @file
+ Windows version of the raw IP4 transmit application
+
+ Copyright (c) 2011-2012, Intel Corporation
+ All rights reserved. This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <RawIp4Tx.h>
+
+
+/**
+ Transmit raw IP4 packets to the remote system.
+
+ Please note that this program must be run with administrator privileges!
+
+ @param [in] argc The number of arguments
+ @param [in] argv The argument value array
+
+ @retval 0 The application exited normally.
+ @retval Other An error occurred.
+**/
+int
+main(
+ int argc,
+ char ** argv
+ )
+{
+ int RetVal;
+ WSADATA WsaData;
+
+ //
+ // Initialize the WinSock layer
+ //
+ RetVal = WSAStartup ( MAKEWORD ( 2, 2 ), &WsaData );
+ if ( 0 == RetVal ) {
+ //
+ // Start the application
+ // See http://msdn.microsoft.com/en-us/library/ms740548(v=vs.85).aspx
+ //
+ RetVal = RawIp4Tx ( argc, argv );
+ if ( WSAEACCES == RetVal ) {
+ printf ( "Requires administrator privileges to run!\r\n" );
+ }
+
+ //
+ // Done with the WinSock layer
+ //
+ WSACleanup ( );
+ }
+
+ //
+ // Return the final result
+ //
+ return RetVal;
+}
diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/ReadMe.txt b/uefi/linaro-edk2/AppPkg/Applications/Sockets/ReadMe.txt
new file mode 100644
index 0000000..6cfa615
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/ReadMe.txt
@@ -0,0 +1,11 @@
+Users of the socket library need to do the following:
+
+• Use the development branch: https://edk2.svn.sourceforge.net/svnroot/edk2/branches/EADK/
+• Create an Efi\StdLib\etc directory on their system or USB flash device
+• Copy the files from StdLib\Efi\StdLib\etc into that directory
+• Edit the files appropriately
+ o Set the correct DNS servers in resolv.conf
+ o Set the search order in host.conf
+• At the EFI shell
+ o Set the device containing the \Efi directory as the default device
+ o Run the socket application
diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/RecvDgram/RecvDgram.c b/uefi/linaro-edk2/AppPkg/Applications/Sockets/RecvDgram/RecvDgram.c
new file mode 100644
index 0000000..8467005
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/RecvDgram/RecvDgram.c
@@ -0,0 +1,116 @@
+/** @file
+ Receive a datagram
+
+ Copyright (c) 2011-2012, Intel Corporation
+ All rights reserved. This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <errno.h>
+#include <string.h>
+#include <Uefi.h>
+#include <unistd.h>
+
+#include <Library/DebugLib.h>
+#include <Library/UefiLib.h>
+
+#include <netinet/in.h>
+
+#include <sys/socket.h>
+#include <sys/time.h>
+
+UINT8 mBuffer[ 65536 ];
+
+/**
+ Receive a datagram
+
+ @param [in] Argc The number of arguments
+ @param [in] Argv The argument value array
+
+ @retval 0 The application exited normally.
+ @retval Other An error occurred.
+**/
+int
+main (
+ IN int Argc,
+ IN char **Argv
+ )
+{
+ struct sockaddr_in Address;
+ socklen_t AddressLength;
+ ssize_t LengthInBytes;
+ int s;
+ int Status;
+ struct timeval Timeout;
+
+
+ DEBUG (( DEBUG_INFO,
+ "%a starting\r\n",
+ Argv[0]));
+
+ //
+ // Get the socket
+ //
+ s = socket ( AF_INET, SOCK_DGRAM, 0 );
+ if ( -1 == s ) {
+ Print ( L"ERROR - Unable to open the socket, errno: %d\r\n", errno );
+ }
+ else {
+ Timeout.tv_sec = 5;
+ Timeout.tv_usec = 0;
+ Status = setsockopt ( s,
+ SOL_SOCKET,
+ SO_RCVTIMEO,
+ &Timeout,
+ sizeof ( Timeout ));
+ if ( -1 == Status ) {
+ Print ( L"ERROR - Unable to set the receive timeout, errno: %d\r\n", errno );
+ }
+ else {
+ AddressLength = sizeof ( Address );
+ LengthInBytes = recvfrom ( s,
+ &mBuffer[0],
+ sizeof ( mBuffer[0]),
+ 0,
+ (struct sockaddr *)&Address,
+ &AddressLength );
+ if ( -1 == LengthInBytes ) {
+ if ( ETIMEDOUT == errno ) {
+ Print ( L"No datagram received\r\n" );
+ }
+ else {
+ Print ( L"ERROR - No datagram received, errno: %d\r\n", errno );
+ }
+ }
+ else {
+ Print ( L"Received %d bytes from %d.%d.%d.%d:%d\r\n",
+ LengthInBytes,
+ (UINT8)Address.sin_addr.s_addr,
+ (UINT8)( Address.sin_addr.s_addr >> 8 ),
+ (UINT8)( Address.sin_addr.s_addr >> 16 ),
+ (UINT8)( Address.sin_addr.s_addr >> 24 ),
+ htons ( Address.sin_port ));
+ }
+ }
+
+ //
+ // Done with the socket
+ //
+ close ( s );
+ }
+
+ //
+ // All done
+ //
+ DEBUG (( DEBUG_INFO,
+ "%a exiting, errno: %d\r\n",
+ Argv[0],
+ errno ));
+ return errno;
+}
diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/RecvDgram/RecvDgram.inf b/uefi/linaro-edk2/AppPkg/Applications/Sockets/RecvDgram/RecvDgram.inf
new file mode 100644
index 0000000..9a9ca71
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/RecvDgram/RecvDgram.inf
@@ -0,0 +1,57 @@
+## @file
+# Receive Datagram Application
+#
+# Copyright (c) 2011-2012, Intel Corporation
+# All rights reserved. This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = RecvDgram
+ FILE_GUID = 929189C9-0670-4c0b-AF7D-135D1550C8C0
+ MODULE_TYPE = UEFI_APPLICATION
+ VERSION_STRING = 1.0
+ ENTRY_POINT = ShellCEntryLib
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF EBC
+#
+
+[Sources]
+ RecvDgram.c
+
+
+[Packages]
+ MdePkg/MdePkg.dec
+ ShellPkg/ShellPkg.dec
+ StdLib/StdLib.dec
+
+
+[LibraryClasses]
+ BaseMemoryLib
+ BsdSocketLib
+ DebugLib
+ DevMedia
+ EfiSocketLib
+ LibC
+ LibMath
+ ShellCEntryLib
+ UefiBootServicesTableLib
+ UefiLib
+# UseSocketDxe
+
+[BuildOptions]
+ INTEL:*_*_*_CC_FLAGS = /Qdiag-disable:181,186
+ MSFT:*_*_*_CC_FLAGS = /Od
+ GCC:*_*_*_CC_FLAGS = -O0 -Wno-unused-variable
+
diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/SetHostName/SetHostName.c b/uefi/linaro-edk2/AppPkg/Applications/Sockets/SetHostName/SetHostName.c
new file mode 100644
index 0000000..2c8001e
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/SetHostName/SetHostName.c
@@ -0,0 +1,100 @@
+/** @file
+ Set the host name
+
+ Copyright (c) 2011-2012, Intel Corporation
+ All rights reserved. This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <errno.h>
+#include <string.h>
+#include <Uefi.h>
+#include <unistd.h>
+
+#include <Library/DebugLib.h>
+#include <Library/UefiLib.h>
+
+#include <sys/socket.h>
+
+char mBuffer[65536];
+
+
+/**
+ Set the host name
+
+ @param [in] Argc The number of arguments
+ @param [in] Argv The argument value array
+
+ @retval 0 The application exited normally.
+ @retval Other An error occurred.
+**/
+int
+main (
+ IN int Argc,
+ IN char **Argv
+ )
+{
+ int AppStatus;
+
+ DEBUG (( DEBUG_INFO,
+ "%a starting\r\n",
+ Argv[0]));
+
+ //
+ // Determine if the host name is specified
+ //
+ AppStatus = 0;
+ if ( 1 < Argc ) {
+ //
+ // Set the host name
+ //
+ AppStatus = sethostname ( Argv[1], strlen ( Argv[1]));
+ if ( -1 == AppStatus ) {
+ switch ( errno ) {
+ default:
+ Print ( L"ERROR - errno: %d\r\n", errno );
+ break;
+
+ case ENODEV:
+ Print ( L"WARNING - Plarform does not support permanent storage!\r\n" );
+ break;
+
+ case ENOMEM:
+ Print ( L"ERROR - Insufficient storage to save host name!\r\n" );
+ break;
+
+ case ENOTSUP:
+ Print ( L"ERROR - Platform does not support environment variable storage!\r\n" );
+ break;
+ }
+ }
+ }
+ else {
+ //
+ // Display the current host name
+ //
+ AppStatus = gethostname ( &mBuffer[0], sizeof ( mBuffer ));
+ if ( -1 == AppStatus ) {
+ Print ( L"ERROR - Unable to get host name, errno: %d\r\n", errno );
+ }
+ else {
+ if ( 0 == mBuffer[0]) {
+ Print ( L"Host name is not set!\r\n" );
+ }
+ else {
+ Print ( L"Host name: %a", &mBuffer[0]);
+ }
+ }
+ }
+
+ //
+ // All done
+ //
+ return errno;
+}
diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/SetHostName/SetHostName.inf b/uefi/linaro-edk2/AppPkg/Applications/Sockets/SetHostName/SetHostName.inf
new file mode 100644
index 0000000..ed1b495
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/SetHostName/SetHostName.inf
@@ -0,0 +1,57 @@
+## @file
+# SetHostName Application
+#
+# Copyright (c) 2011-2012, Intel Corporation
+# All rights reserved. This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = SetHostName
+ FILE_GUID = 4BC80B15-255D-4858-8072-51D6D98CF90E
+ MODULE_TYPE = UEFI_APPLICATION
+ VERSION_STRING = 1.0
+ ENTRY_POINT = ShellCEntryLib
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF EBC
+#
+
+[Sources]
+ SetHostName.c
+
+
+[Packages]
+ MdePkg/MdePkg.dec
+ ShellPkg/ShellPkg.dec
+ StdLib/StdLib.dec
+
+
+[LibraryClasses]
+ BaseMemoryLib
+ BsdSocketLib
+ DebugLib
+ DevMedia
+ EfiSocketLib
+ LibC
+ LibMath
+ ShellCEntryLib
+ UefiBootServicesTableLib
+ UefiLib
+# UseSocketDxe
+
+[BuildOptions]
+ INTEL:*_*_*_CC_FLAGS = /Qdiag-disable:181,186
+ MSFT:*_*_*_CC_FLAGS = /Od
+ GCC:*_*_*_CC_FLAGS = -O0 -Wno-unused-variable
+
diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/SetSockOpt/SetSockOpt.c b/uefi/linaro-edk2/AppPkg/Applications/Sockets/SetSockOpt/SetSockOpt.c
new file mode 100644
index 0000000..bba8f4b
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/SetSockOpt/SetSockOpt.c
@@ -0,0 +1,381 @@
+/** @file
+ Set the socket options
+
+ Copyright (c) 2011-2012, Intel Corporation
+ All rights reserved. This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <Uefi.h>
+#include <unistd.h>
+
+#include <Library/DebugLib.h>
+#include <Library/UefiLib.h>
+
+#include <sys/socket.h>
+#include <sys/time.h>
+
+typedef enum _DATA_TYPE {
+ DATA_TYPE_UNKNOWN = 0,
+ DATA_TYPE_INT32_DECIMAL,
+ DATA_TYPE_SOCKET_TYPE,
+ DATA_TYPE_TIMEVAL
+} DATA_TYPE;
+
+typedef struct {
+ char * pOptionName;
+ int OptionValue;
+ int OptionLevel;
+ BOOLEAN bSetAllowed;
+ DATA_TYPE DataType;
+} OPTIONS;
+
+CONST OPTIONS mOptions[] = {
+ { "SO_ACCEPTCONN", SO_ACCEPTCONN, SOL_SOCKET, FALSE, DATA_TYPE_UNKNOWN },
+ { "SO_BROADCAST", SO_BROADCAST, SOL_SOCKET, TRUE, DATA_TYPE_UNKNOWN },
+ { "SO_DEBUG", SO_DEBUG, SOL_SOCKET, TRUE, DATA_TYPE_UNKNOWN },
+ { "SO_DONTROUTE", SO_DONTROUTE, SOL_SOCKET, TRUE, DATA_TYPE_UNKNOWN },
+ { "SO_ERROR", SO_ERROR, SOL_SOCKET, FALSE, DATA_TYPE_UNKNOWN },
+ { "SO_KEEPALIVE", SO_KEEPALIVE, SOL_SOCKET, TRUE, DATA_TYPE_UNKNOWN },
+ { "SO_OOBINLINE", SO_OOBINLINE, SOL_SOCKET, TRUE, DATA_TYPE_UNKNOWN },
+ { "SO_OVERFLOWED", SO_OVERFLOWED, SOL_SOCKET, TRUE, DATA_TYPE_UNKNOWN },
+ { "SO_RCVBUF", SO_RCVBUF, SOL_SOCKET, TRUE, DATA_TYPE_INT32_DECIMAL },
+ { "SO_RCVLOWAT", SO_RCVLOWAT, SOL_SOCKET, TRUE, DATA_TYPE_UNKNOWN },
+ { "SO_RCVTIMEO", SO_RCVTIMEO, SOL_SOCKET, TRUE, DATA_TYPE_TIMEVAL },
+ { "SO_REUSEADDR", SO_REUSEADDR, SOL_SOCKET, TRUE, DATA_TYPE_UNKNOWN },
+ { "SO_REUSEPORT", SO_REUSEPORT, SOL_SOCKET, TRUE, DATA_TYPE_UNKNOWN },
+ { "SO_SNDBUF", SO_SNDBUF, SOL_SOCKET, TRUE, DATA_TYPE_INT32_DECIMAL },
+ { "SO_SNDLOWAT", SO_SNDLOWAT, SOL_SOCKET, TRUE, DATA_TYPE_UNKNOWN },
+ { "SO_SNDTIMEO", SO_SNDTIMEO, SOL_SOCKET, TRUE, DATA_TYPE_UNKNOWN },
+ { "SO_TIMESTAMP", SO_TIMESTAMP, SOL_SOCKET, TRUE, DATA_TYPE_UNKNOWN },
+ { "SO_TYPE", SO_TYPE, SOL_SOCKET, FALSE, DATA_TYPE_SOCKET_TYPE },
+ { "SO_USELOOPBACK", SO_USELOOPBACK, SOL_SOCKET, TRUE, DATA_TYPE_UNKNOWN }
+};
+
+
+UINT8 mBuffer[ 65536 ];
+UINT8 mValue[ 65536 ];
+char * mSocketType[] = {
+ "SOCK_STREAM",
+ "SOCK_DGRAM",
+ "SOCK_RAW",
+ "SOCK_RDM",
+ "SOCK_SEQPACKET"
+};
+
+void
+DisplayOption (
+ CONST OPTIONS * pOption,
+ socklen_t LengthInBytes,
+ BOOLEAN bDisplayUpdate,
+ BOOLEAN bDisplayCrLf
+ )
+{
+ UINT8 * pEnd;
+ char * pString;
+ union {
+ UINT8 * u8;
+ INT32 * i32;
+ struct timeval * TimeVal;
+ } Value;
+
+ //
+ // Display the value length
+ //
+ if ( !bDisplayUpdate ) {
+ Print ( L"LengthInBytes: %d\r\n", LengthInBytes );
+ Print ( L"%a: ", pOption->pOptionName );
+ }
+ else {
+ Print ( L" --> " );
+ }
+
+ //
+ // Display the value
+ //
+ Value.u8 = &mBuffer[0];
+ switch ( pOption->DataType ) {
+ case DATA_TYPE_UNKNOWN:
+ Print ( L"%a:", pOption->pOptionName );
+ pEnd = &Value.u8[ LengthInBytes ];
+ while ( pEnd > Value.u8 ) {
+ Print ( L" %02x", *Value.u8 );
+ Value.u8 += 1;
+ }
+ break;
+
+ case DATA_TYPE_INT32_DECIMAL:
+ if ( 4 == LengthInBytes ) {
+ Print ( L"%d", *Value.i32 );
+ }
+ else {
+ errno = ( 4 > LengthInBytes ) ? EBUFSIZE : ERANGE;
+ Print ( L"\r\nERROR - Invalid length, errno: %d\r\n", errno );
+ }
+ break;
+
+ case DATA_TYPE_SOCKET_TYPE:
+ if ( 4 == LengthInBytes ) {
+ if (( SOCK_STREAM <= *Value.i32 ) && ( SOCK_SEQPACKET >= *Value.i32 )) {
+ pString = mSocketType[ *Value.i32 - SOCK_STREAM ];
+ Print ( L"%a", pString );
+ }
+ else {
+ Print ( L"%08x (unknown type)", *Value.i32 );
+ }
+ }
+ else {
+ errno = ( 4 > LengthInBytes ) ? EBUFSIZE : ERANGE;
+ Print ( L"\r\nERROR - Invalid length, errno: %d\r\n", errno );
+ }
+ break;
+
+ case DATA_TYPE_TIMEVAL:
+ if ( sizeof ( *Value.TimeVal ) == LengthInBytes ) {
+ if (( 0 == Value.TimeVal->tv_sec )
+ && ( 0 == Value.TimeVal->tv_usec )) {
+ Print ( L"Infinite" );
+ }
+ else {
+ Print ( L"%d.%06d sec",
+ Value.TimeVal->tv_sec,
+ Value.TimeVal->tv_usec );
+ }
+ }
+ else {
+ errno = ( 4 > LengthInBytes ) ? EBUFSIZE : ERANGE;
+ Print ( L"\r\nERROR - Invalid length, errno: %d\r\n", errno );
+ }
+ break;
+ }
+
+ //
+ // Terminate the line
+ //
+ if ( bDisplayCrLf ) {
+ Print ( L"\r\n" );
+ }
+}
+
+socklen_t
+GetOptionValue (
+ CONST OPTIONS * pOption,
+ char * pValue
+ )
+{
+ socklen_t BytesToWrite;
+ union {
+ UINT8 * u8;
+ INT32 * i32;
+ struct timeval * TimeVal;
+ } Value;
+ int Values;
+
+ //
+ // Assume failure
+ //
+ errno = EINVAL;
+ BytesToWrite = 0;
+
+ //
+ // Determine the type of parameter
+ //
+ if ( pOption->bSetAllowed ) {
+ Value.u8 = &mValue[0];
+ switch ( pOption->DataType ) {
+ default:
+ break;
+
+ case DATA_TYPE_INT32_DECIMAL:
+ Values = sscanf ( pValue, "%d", Value.i32 );
+ if ( 1 == Values ) {
+ BytesToWrite = sizeof ( *Value.i32);
+ errno = 0;
+ }
+ break;
+
+ case DATA_TYPE_TIMEVAL:
+ Values = sscanf ( pValue, "%d.%d",
+ &Value.TimeVal->tv_sec,
+ &Value.TimeVal->tv_usec );
+ if (( 2 == Values )
+ && ( 0 <= Value.TimeVal->tv_sec )
+ && ( 0 <= Value.TimeVal->tv_usec )
+ && ( 1000000 > Value.TimeVal->tv_usec )){
+ BytesToWrite = sizeof ( *Value.TimeVal );
+ errno = 0;
+ }
+ }
+ }
+
+ //
+ // Display the error
+ //
+ if ( 0 == BytesToWrite ) {
+ Print ( L"ERROR - Invalid value!\r\n" );
+ }
+
+ //
+ // Return the number of bytes to be written
+ //
+ return BytesToWrite;
+}
+
+
+/**
+ Set the socket options
+
+ @param [in] Argc The number of arguments
+ @param [in] Argv The argument value array
+
+ @retval 0 The application exited normally.
+ @retval Other An error occurred.
+**/
+int
+main (
+ IN int Argc,
+ IN char **Argv
+ )
+{
+ socklen_t BytesToWrite;
+ socklen_t LengthInBytes;
+ CONST OPTIONS * pEnd;
+ CONST OPTIONS * pOption;
+ int s;
+ int Status;
+
+ DEBUG (( DEBUG_INFO,
+ "%a starting\r\n",
+ Argv[0]));
+
+ //
+ // Parse the socket option
+ //
+ pOption = &mOptions[0];
+ pEnd = &pOption[sizeof ( mOptions ) / sizeof ( mOptions[0])];
+ if ( 2 <= Argc ) {
+ while ( pEnd > pOption ) {
+ if ( 0 == strcmp ( Argv[1], pOption->pOptionName )) {
+ break;
+ }
+ pOption += 1;
+ }
+ if ( pEnd <= pOption ) {
+ Print ( L"ERROR: Invalid option: %a\r\n", Argv[1]);
+ Argc = 1;
+ }
+ }
+
+ //
+ // Display the help if necessary
+ //
+ if (( 2 > Argc ) || ( 3 < Argc )) {
+ Print ( L"%a <option>\r\n", Argv[0]);
+ Print ( L"\r\n" );
+ Print ( L"Option one of:\r\n" );
+ pOption = &mOptions[0];
+ while ( pEnd > pOption ) {
+ Print ( L" %a: %a\r\n",
+ pOption->pOptionName,
+ pOption->bSetAllowed ? "get/set" : "get" );
+ pOption += 1;
+ }
+ errno = EINVAL;
+ }
+ else {
+ //
+ // Determine if the value is to be set
+ //
+ BytesToWrite = 0;
+ if (( 3 > Argc )
+ || ( 0 < ( BytesToWrite = GetOptionValue ( pOption, Argv[2])))) {
+ //
+ // Get the socket
+ //
+ s = socket ( AF_INET, 0, 0 );
+ if ( -1 == s ) {
+ Print ( L"ERROR - Unable to open the socket, errno: %d\r\n", errno );
+ }
+ else {
+ //
+ // Display the option value
+ //
+ LengthInBytes = sizeof ( mBuffer );
+ Status = getsockopt ( s,
+ pOption->OptionLevel,
+ pOption->OptionValue,
+ &mBuffer,
+ &LengthInBytes );
+ if ( -1 == Status ) {
+ Print ( L"ERROR - getsockopt failed, errno: %d\r\n", errno );
+ }
+ else {
+ DisplayOption ( pOption,
+ LengthInBytes,
+ FALSE,
+ (BOOLEAN)( 0 == BytesToWrite ));
+
+ //
+ // Determine if the value is to be set
+ //
+ if (( 0 < BytesToWrite )
+ && ( BytesToWrite == LengthInBytes )) {
+ //
+ // Set the option value
+ //
+ Status = setsockopt ( s,
+ pOption->OptionLevel,
+ pOption->OptionValue,
+ &mValue,
+ BytesToWrite );
+ if ( -1 == Status ) {
+ Print ( L"ERROR - setsockopt failed, errno: %d\r\n", errno );
+ }
+ else {
+ //
+ // Display the updated option value
+ //
+ Status = getsockopt ( s,
+ pOption->OptionLevel,
+ pOption->OptionValue,
+ &mBuffer,
+ &LengthInBytes );
+ if ( -1 == Status ) {
+ Print ( L"ERROR - getsockopt failed, errno: %d\r\n", errno );
+ }
+ else {
+ DisplayOption ( pOption,
+ LengthInBytes,
+ TRUE,
+ TRUE );
+ }
+ }
+ }
+ }
+
+ //
+ // Done with the socket
+ //
+ close ( s );
+ }
+ }
+ }
+
+ //
+ // All done
+ //
+ DEBUG (( DEBUG_INFO,
+ "%a exiting, errno: %d\r\n",
+ Argv[0],
+ errno ));
+ return errno;
+}
diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/SetSockOpt/SetSockOpt.inf b/uefi/linaro-edk2/AppPkg/Applications/Sockets/SetSockOpt/SetSockOpt.inf
new file mode 100644
index 0000000..e088be7
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/SetSockOpt/SetSockOpt.inf
@@ -0,0 +1,57 @@
+## @file
+# SetHostName Application
+#
+# Copyright (c) 2011-2012, Intel Corporation
+# All rights reserved. This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = SetSockOpt
+ FILE_GUID = 6E851687-A7A9-4aa2-8DD0-673E03E51433
+ MODULE_TYPE = UEFI_APPLICATION
+ VERSION_STRING = 1.0
+ ENTRY_POINT = ShellCEntryLib
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF EBC
+#
+
+[Sources]
+ SetSockOpt.c
+
+
+[Packages]
+ MdePkg/MdePkg.dec
+ ShellPkg/ShellPkg.dec
+ StdLib/StdLib.dec
+
+
+[LibraryClasses]
+ BaseMemoryLib
+ BsdSocketLib
+ DebugLib
+ DevMedia
+ EfiSocketLib
+ LibC
+ LibMath
+ ShellCEntryLib
+ UefiBootServicesTableLib
+ UefiLib
+# UseSocketDxe
+
+[BuildOptions]
+ INTEL:*_*_*_CC_FLAGS = /Qdiag-disable:181,186
+ MSFT:*_*_*_CC_FLAGS = /Od
+ GCC:*_*_*_CC_FLAGS = -O0 -Wno-unused-variable
+
diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/Sockets.inc b/uefi/linaro-edk2/AppPkg/Applications/Sockets/Sockets.inc
new file mode 100644
index 0000000..4ad109f
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/Sockets.inc
@@ -0,0 +1,42 @@
+
+################################################################################
+# Socket Applications
+################################################################################
+
+[Components]
+ AppPkg/Applications/Sockets/DataSink/DataSink.inf
+ AppPkg/Applications/Sockets/DataSource/DataSource.inf
+ AppPkg/Applications/Sockets/GetAddrInfo/GetAddrInfo.inf
+ AppPkg/Applications/Sockets/GetHostByAddr/GetHostByAddr.inf
+ AppPkg/Applications/Sockets/GetHostByDns/GetHostByDns.inf
+ AppPkg/Applications/Sockets/GetHostByName/GetHostByName.inf
+ AppPkg/Applications/Sockets/GetNameInfo/GetNameInfo.inf
+ AppPkg/Applications/Sockets/GetNetByAddr/GetNetByAddr.inf
+ AppPkg/Applications/Sockets/GetNetByName/GetNetByName.inf
+ AppPkg/Applications/Sockets/GetServByName/GetServByName.inf
+ AppPkg/Applications/Sockets/GetServByPort/GetServByPort.inf
+ AppPkg/Applications/Sockets/OobRx/OobRx.inf
+ AppPkg/Applications/Sockets/OobTx/OobTx.inf
+ AppPkg/Applications/Sockets/RawIp4Rx/RawIp4Rx.inf
+ AppPkg/Applications/Sockets/RawIp4Tx/RawIp4Tx.inf
+ AppPkg/Applications/Sockets/RecvDgram/RecvDgram.inf
+ AppPkg/Applications/Sockets/SetHostName/SetHostName.inf
+ AppPkg/Applications/Sockets/SetSockOpt/SetSockOpt.inf
+ AppPkg/Applications/Sockets/WebServer/WebServer.inf {
+ <LibraryClasses>
+ CpuLib|MdePkg/Library/BaseCpuLib/BaseCpuLib.inf
+ DxeServicesTableLib|MdePkg/Library/DxeServicesTableLib/DxeServicesTableLib.inf
+ MtrrLib|UefiCpuPkg/Library/MtrrLib/MtrrLib.inf
+
+ <PcdsFixedAtBuild>
+ gAppPkgTokenSpaceGuid.WebServer_HttpPort|80
+ }
+
+################################################################################
+# The following application requires TimerLib (platform specific library)
+################################################################################
+
+[Components]
+# AppPkg/Applications/Sockets/TftpServer/TftpServer.inf
+
+
diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/TftpServer/TftpServer.c b/uefi/linaro-edk2/AppPkg/Applications/Sockets/TftpServer/TftpServer.c
new file mode 100644
index 0000000..30d9dae
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/TftpServer/TftpServer.c
@@ -0,0 +1,2367 @@
+/** @file
+ This is a simple TFTP server application
+
+ Copyright (c) 2011, 2012, Intel Corporation
+ All rights reserved. This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <TftpServer.h>
+
+TSDT_TFTP_SERVER mTftpServer; ///< TFTP server's control structure
+volatile BOOLEAN mbTftpServerExit; ///< Set TRUE to cause TFTP server to exit
+
+
+/**
+ Read file data into a buffer
+
+ @param [in] pContext Connection context structure address
+
+ @retval TRUE if a read error occurred
+
+**/
+BOOLEAN
+BufferFill (
+ IN TSDT_CONNECTION_CONTEXT * pContext
+ )
+{
+ BOOLEAN bReadError;
+ size_t BytesRead;
+ UINT64 LengthInBytes;
+
+ DBG_ENTER ( );
+
+ //
+ // Use break instead of goto
+ //
+ bReadError = FALSE;
+ for ( ; ; ) {
+ //
+ // Determine if there is any work to do
+ //
+ LengthInBytes = DIM ( pContext->FileData ) >> 1;
+ if (( pContext->ValidBytes > LengthInBytes )
+ || ( 0 == pContext->BytesRemaining )) {
+ break;
+ }
+
+ //
+ // Determine the number of bytes to read
+ //
+ if ( LengthInBytes > pContext->BytesRemaining ) {
+ LengthInBytes = pContext->BytesRemaining;
+ }
+
+ //
+ // Read in the next portion of the file
+ //
+ BytesRead = fread ( pContext->pFill,
+ 1,
+ (size_t)LengthInBytes,
+ pContext->File );
+ if ( -1 == BytesRead ) {
+ bReadError = TRUE;
+ break;
+ }
+
+ //
+ // Account for the file data read
+ //
+ pContext->BytesRemaining -= BytesRead;
+ pContext->ValidBytes += BytesRead;
+ DEBUG (( DEBUG_FILE_BUFFER,
+ "0x%08x: Buffer filled with %Ld bytes, %Ld bytes ramaining\r\n",
+ pContext->pFill,
+ BytesRead,
+ pContext->BytesRemaining ));
+
+ //
+ // Set the next buffer location
+ //
+ pContext->pFill += BytesRead;
+ if ( pContext->pEnd <= pContext->pFill ) {
+ pContext->pFill = &pContext->FileData[ 0 ];
+ }
+
+ //
+ // Verify that the end of the buffer is reached
+ //
+ ASSERT ( 0 == ( DIM ( pContext->FileData ) & 1 ));
+ break;
+ }
+
+ //
+ // Return the read status
+ //
+ DBG_EXIT ( );
+ return bReadError;
+}
+
+
+/**
+ Add a connection context to the list of connection contexts.
+
+ @param [in] pTftpServer Address of the ::TSDT_TFTP_SERVER structure
+ @param [in] SocketFd Socket file descriptor
+
+ @retval Context structure address, NULL if allocation fails
+
+**/
+TSDT_CONNECTION_CONTEXT *
+ContextAdd (
+ IN TSDT_TFTP_SERVER * pTftpServer,
+ IN int SocketFd
+ )
+{
+ TSDT_CONNECTION_CONTEXT * pContext;
+ TFTP_PACKET * pEnd;
+ TFTP_PACKET * pPacket;
+
+ DBG_ENTER ( );
+
+ //
+ // Allocate a new context
+ //
+ pContext = (TSDT_CONNECTION_CONTEXT *)AllocateZeroPool ( sizeof ( *pContext ));
+ if ( NULL != pContext ) {
+ //
+ // Initialize the context
+ //
+ pContext->SocketFd = SocketFd;
+ CopyMem ( &pContext->RemoteAddress,
+ &pTftpServer->RemoteAddress,
+ sizeof ( pContext->RemoteAddress ));
+ pContext->BlockSize = 512;
+
+ //
+ // Buffer management
+ //
+ pContext->pFill = &pContext->FileData[ 0 ];
+ pContext->pEnd = &pContext->FileData[ sizeof ( pContext->FileData )];
+ pContext->pBuffer = pContext->pFill;
+
+ //
+ // Window management
+ //
+ pContext->MaxTimeout = MultU64x32 ( PcdGet32 ( Tftp_MaxTimeoutInSec ),
+ 2 * 1000 * 1000 * 1000 );
+ pContext->Rtt2x = pContext->MaxTimeout;
+ pContext->WindowSize = MAX_PACKETS;
+ WindowTimeout ( pContext );
+
+ //
+ // Place the packets on the free list
+ //
+ pPacket = &pContext->Tx[ 0 ];
+ pEnd = &pPacket[ DIM ( pContext->Tx )];
+ while ( pEnd > pPacket ) {
+ PacketFree ( pContext, pPacket );
+ pPacket += 1;
+ }
+
+ //
+ // Display the new context
+ //
+ if ( AF_INET == pTftpServer->RemoteAddress.v4.sin_family ) {
+ DEBUG (( DEBUG_PORT_WORK,
+ "0x%08x: Context for %d.%d.%d.%d:%d\r\n",
+ pContext,
+ (UINT8)pTftpServer->RemoteAddress.v4.sin_addr.s_addr,
+ (UINT8)( pTftpServer->RemoteAddress.v4.sin_addr.s_addr >> 8 ),
+ (UINT8)( pTftpServer->RemoteAddress.v4.sin_addr.s_addr >> 16 ),
+ (UINT8)( pTftpServer->RemoteAddress.v4.sin_addr.s_addr >> 24 ),
+ htons ( pTftpServer->RemoteAddress.v4.sin_port )));
+ }
+ else {
+ DEBUG (( DEBUG_PORT_WORK,
+ "0x%08x: Context for [%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]:%d\r\n",
+ pContext,
+ pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 0 ],
+ pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 1 ],
+ pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 2 ],
+ pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 3 ],
+ pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 4 ],
+ pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 5 ],
+ pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 6 ],
+ pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 7 ],
+ pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 8 ],
+ pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 9 ],
+ pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 10 ],
+ pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 11 ],
+ pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 12 ],
+ pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 13 ],
+ pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 14 ],
+ pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 15 ],
+ htons ( pTftpServer->RemoteAddress.v6.sin6_port )));
+ }
+
+ //
+ // Add the context to the context list
+ //
+ pContext->pNext = pTftpServer->pContextList;
+ pTftpServer->pContextList = pContext;
+ }
+
+ //
+ // Return the connection context
+ //
+ DBG_EXIT_STATUS ( pContext );
+ return pContext;
+}
+
+
+/**
+ Locate a remote connection context.
+
+ @param [in] pTftpServer Address of the ::TSDT_TFTP_SERVER structure
+ @param [in] pIpAddress The start of the remote IP address in network order
+ @param [in] Port The remote port number
+
+ @retval Context structure address, NULL if not found
+
+**/
+TSDT_CONNECTION_CONTEXT *
+ContextFind (
+ IN TSDT_TFTP_SERVER * pTftpServer
+ )
+{
+ TSDT_CONNECTION_CONTEXT * pContext;
+
+ DBG_ENTER ( );
+
+ //
+ // Walk the list of connection contexts
+ //
+ pContext = pTftpServer->pContextList;
+ while ( NULL != pContext ) {
+ //
+ // Attempt to locate the remote network connection
+ //
+ if ( 0 == memcmp ( &pTftpServer->RemoteAddress,
+ &pContext->RemoteAddress,
+ pTftpServer->RemoteAddress.v6.sin6_len )) {
+ //
+ // The connection was found
+ //
+ DEBUG (( DEBUG_TFTP_REQUEST,
+ "0x%08x: pContext found\r\n",
+ pContext ));
+ break;
+ }
+
+ //
+ // Set the next context
+ //
+ pContext = pContext->pNext;
+ }
+
+ //
+ // Return the connection context structure address
+ //
+ DBG_EXIT_HEX ( pContext );
+ return pContext;
+}
+
+
+/**
+ Remove a context from the list.
+
+ @param [in] pTftpServer Address of the ::TSDT_TFTP_SERVER structure
+ @param [in] pContext Address of a ::TSDT_CONNECTION_CONTEXT structure
+
+**/
+VOID
+ContextRemove (
+ IN TSDT_TFTP_SERVER * pTftpServer,
+ IN TSDT_CONNECTION_CONTEXT * pContext
+ )
+{
+ TSDT_CONNECTION_CONTEXT * pNextContext;
+ TSDT_CONNECTION_CONTEXT * pPreviousContext;
+
+ DBG_ENTER ( );
+
+ //
+ // Attempt to locate the context in the list
+ //
+ pPreviousContext = NULL;
+ pNextContext = pTftpServer->pContextList;
+ while ( NULL != pNextContext ) {
+ //
+ // Determine if the context was found
+ //
+ if ( pNextContext == pContext ) {
+ //
+ // Remove the context from the list
+ //
+ if ( NULL == pPreviousContext ) {
+ pTftpServer->pContextList = pContext->pNext;
+ }
+ else {
+ pPreviousContext->pNext = pContext->pNext;
+ }
+ break;
+ }
+
+ //
+ // Set the next context
+ //
+ pPreviousContext = pNextContext;
+ pNextContext = pNextContext->pNext;
+ }
+
+ //
+ // Determine if the context was found
+ //
+ if ( NULL != pContext ) {
+ //
+ // Return the resources
+ //
+ gBS->FreePool ( pContext );
+ }
+
+ DBG_EXIT ( );
+}
+
+
+/**
+ Queue data packets for transmission
+
+ @param [in] pContext Connection context structure address
+
+ @retval TRUE if a read error occurred
+
+**/
+BOOLEAN
+PacketFill (
+ IN TSDT_CONNECTION_CONTEXT * pContext
+ )
+{
+ BOOLEAN bReadError;
+ UINT64 LengthInBytes;
+ UINT8 * pBuffer;
+ TFTP_PACKET * pPacket;
+
+ DBG_ENTER ( );
+
+ //
+ // Use break instead of goto
+ //
+ bReadError = FALSE;
+ for ( ; ; ) {
+ //
+ // Fill the buffer if necessary
+ //
+ bReadError = BufferFill ( pContext );
+ if ( bReadError ) {
+ //
+ // File access mode not supported
+ //
+ DEBUG (( DEBUG_ERROR | DEBUG_TFTP_REQUEST,
+ "ERROR - File read failure!\r\n" ));
+
+ //
+ // Tell the client of the error
+ //
+ SendError ( pContext,
+ TFTP_ERROR_SEE_MSG,
+ (UINT8 *)"Read failure" );
+ break;
+ }
+
+ //
+ // Determine if any packets can be filled
+ //
+ if ( pContext->bEofSent
+ || ( NULL == pContext->pFreeList )) {
+ //
+ // All of the packets are filled
+ //
+ break;
+ }
+
+ //
+ // Set the TFTP opcode and block number
+ //
+ pPacket = PacketGet ( pContext );
+ pBuffer = &pPacket->TxBuffer[ 0 ];
+ *pBuffer++ = 0;
+ *pBuffer++ = TFTP_OP_DATA;
+ *pBuffer++ = (UINT8)( pContext->BlockNumber >> 8 );
+ *pBuffer++ = (UINT8)pContext->BlockNumber;
+
+ //
+ // Determine how much data needs to be sent
+ //
+ LengthInBytes = pContext->BlockSize;
+ if (( pContext->BytesToSend < TFTP_MAX_BLOCK_SIZE )
+ && ( LengthInBytes > pContext->BytesToSend )) {
+ LengthInBytes = pContext->BytesToSend;
+ pContext->bEofSent = TRUE;
+ }
+ DEBUG (( DEBUG_TX_PACKET,
+ "0x%08x: Packet, Block %d filled with %d bytes\r\n",
+ pPacket,
+ pContext->BlockNumber,
+ (UINT32)LengthInBytes ));
+
+ //
+ // Copy the file data into the packet
+ //
+ pPacket->TxBytes = (ssize_t)( 2 + 2 + LengthInBytes );
+ if ( 0 < LengthInBytes ) {
+ CopyMem ( pBuffer,
+ pContext->pBuffer,
+ (UINTN)LengthInBytes );
+ DEBUG (( DEBUG_FILE_BUFFER,
+ "0x%08x: Buffer consumed %d bytes of file data\r\n",
+ pContext->pBuffer,
+ LengthInBytes ));
+
+ //
+ // Account for the file data consumed
+ //
+ pContext->ValidBytes -= LengthInBytes;
+ pContext->BytesToSend -= LengthInBytes;
+ pContext->pBuffer += LengthInBytes;
+ if ( pContext->pEnd <= pContext->pBuffer ) {
+ pContext->pBuffer = &pContext->FileData[ 0 ];
+ }
+ }
+
+ //
+ // Queue the packet for transmission
+ //
+ PacketQueue ( pContext, pPacket );
+ }
+
+ //
+ // Return the read status
+ //
+ DBG_EXIT ( );
+ return bReadError;
+}
+
+
+/**
+ Free the packet
+
+ @param [in] pContext Address of a ::TSDT_CONNECTION_CONTEXT structure
+ @param [in] pPacket Address of a ::TFTP_PACKET structure
+
+**/
+VOID
+PacketFree(
+ IN TSDT_CONNECTION_CONTEXT * pContext,
+ IN TFTP_PACKET * pPacket
+ )
+{
+ DBG_ENTER ( );
+
+ //
+ // Don't free the error packet
+ //
+ if ( pPacket != &pContext->ErrorPacket ) {
+ //
+ // Place the packet on the free list
+ //
+ pPacket->pNext = pContext->pFreeList;
+ pContext->pFreeList = pPacket;
+ DEBUG (( DEBUG_TX_PACKET,
+ "0x%08x: Packet queued to free list\r\n",
+ pPacket ));
+ }
+
+ DBG_EXIT ( );
+}
+
+
+/**
+ Get a packet from the free list for transmission
+
+ @param [in] pContext Address of a ::TSDT_CONNECTION_CONTEXT structure
+
+ @retval Address of a ::TFTP_PACKET structure
+
+**/
+TFTP_PACKET *
+PacketGet (
+ IN TSDT_CONNECTION_CONTEXT * pContext
+ )
+{
+ TFTP_PACKET * pPacket;
+
+ DBG_ENTER ( );
+
+ //
+ // Get the next packet from the free list
+ //
+ pPacket = pContext->pFreeList;
+ if ( NULL != pPacket ) {
+ pContext->pFreeList = pPacket->pNext;
+ pPacket->RetryCount = 0;
+ DEBUG (( DEBUG_TX_PACKET,
+ "0x%08x: Packet removed from free list\r\n",
+ pPacket ));
+ }
+
+ //
+ // Return the packet
+ //
+ DBG_EXIT_HEX ( pPacket );
+ return pPacket;
+}
+
+
+/**
+ Queue the packet for transmission
+
+ @param [in] pContext Address of a ::TSDT_CONNECTION_CONTEXT structure
+ @param [in] pPacket Address of a ::TFTP_PACKET structure
+
+ @retval TRUE if a transmission error has occurred
+
+**/
+BOOLEAN
+PacketQueue (
+ IN TSDT_CONNECTION_CONTEXT * pContext,
+ IN TFTP_PACKET * pPacket
+ )
+{
+ BOOLEAN bTransmitError;
+ TFTP_PACKET * pTail;
+ EFI_STATUS Status;
+
+ DBG_ENTER ( );
+
+ //
+ // Account for this data block
+ //
+ pPacket->BlockNumber = pContext->BlockNumber;
+ pContext->BlockNumber += 1;
+
+ //
+ // Queue the packet for transmission
+ //
+ pTail = pContext->pTxTail;
+ if ( NULL == pTail ) {
+ pContext->pTxHead = pPacket;
+ }
+ else {
+ pTail->pNext = pPacket;
+ }
+ pContext->pTxTail = pPacket;
+ pPacket->pNext = NULL;
+ DEBUG (( DEBUG_TX_PACKET,
+ "0x%08x: Packet queued to TX list\r\n",
+ pPacket ));
+
+ //
+ // Start the transmission if necessary
+ //
+ bTransmitError = FALSE;
+ if ( pContext->PacketsInWindow < pContext->WindowSize ) {
+ Status = PacketTx ( pContext, pPacket );
+ bTransmitError = (BOOLEAN)( EFI_ERROR ( Status ));
+ }
+
+ //
+ // Return the transmit status
+ //
+ DBG_EXIT_TF ( bTransmitError );
+ return bTransmitError;
+}
+
+
+/**
+ Remove a packet from the transmit queue
+
+ @param [in] pContext Address of a ::TSDT_CONNECTION_CONTEXT structure
+
+**/
+TFTP_PACKET *
+PacketRemove(
+ IN TSDT_CONNECTION_CONTEXT * pContext
+ )
+{
+ TFTP_PACKET * pNext;
+ TFTP_PACKET * pPacket;
+
+ DBG_ENTER ( );
+
+ //
+ // Remove a packet from the transmit queue
+ //
+ //
+ pPacket = pContext->pTxHead;
+ if ( NULL != pPacket ) {
+ pNext = pPacket->pNext;
+ pContext->pTxHead = pNext;
+ if ( NULL == pNext ) {
+ pContext->pTxTail = NULL;
+ }
+ DEBUG (( DEBUG_TX_PACKET,
+ "0x%08x: Packet removed from TX list\r\n",
+ pPacket ));
+
+ //
+ // Remove this packet from the window
+ //
+ pContext->PacketsInWindow -= 1;
+ }
+
+ //
+ // Return the packet
+ //
+ DBG_EXIT_HEX ( pPacket );
+ return pPacket;
+}
+
+
+/**
+ Transmit the packet
+
+ @param [in] pContext Address of a ::TSDT_CONNECTION_CONTEXT structure
+ @param [in] pPacket Address of a ::TFTP_PACKET structure
+
+ @retval EFI_SUCCESS Message processed successfully
+
+**/
+EFI_STATUS
+PacketTx (
+ IN TSDT_CONNECTION_CONTEXT * pContext,
+ IN TFTP_PACKET * pPacket
+ )
+{
+ ssize_t LengthInBytes;
+ EFI_STATUS Status;
+
+ DBG_ENTER ( );
+
+ //
+ // Assume success
+ //
+ Status = EFI_SUCCESS;
+
+ //
+ // Determine if this packet should be transmitted
+ //
+ if ( PcdGet32 ( Tftp_MaxRetry ) >= pPacket->RetryCount ) {
+ pPacket->RetryCount += 1;
+
+ //
+ // Display the operation
+ //
+ DEBUG (( DEBUG_TX_PACKET,
+ "0x%08x: Packet transmiting\r\n",
+ pPacket ));
+ DEBUG (( DEBUG_TX,
+ "0x%08x: pContext sending 0x%08x bytes\r\n",
+ pContext,
+ pPacket->TxBytes ));
+
+ //
+ // Keep track of when the packet was transmitted
+ //
+ if ( PcdGetBool ( Tftp_HighSpeed )) {
+ pPacket->TxTime = GetPerformanceCounter ( );
+ }
+
+ //
+ // Send the TFTP packet
+ //
+ pContext->PacketsInWindow += 1;
+ LengthInBytes = sendto ( pContext->SocketFd,
+ &pPacket->TxBuffer[ 0 ],
+ pPacket->TxBytes,
+ 0,
+ (struct sockaddr *)&pContext->RemoteAddress,
+ pContext->RemoteAddress.sin6_len );
+ if ( -1 == LengthInBytes ) {
+ DEBUG (( DEBUG_ERROR | DEBUG_TX,
+ "ERROR - Transmit failure, errno: 0x%08x\r\n",
+ errno ));
+ pContext->PacketsInWindow -= 1;
+ Status = EFI_DEVICE_ERROR;
+ }
+ }
+ else {
+ //
+ // Too many retries
+ //
+ Status = EFI_NO_RESPONSE;
+ DEBUG (( DEBUG_WARN | DEBUG_WINDOW,
+ "WARNING - No response from TFTP client\r\n" ));
+ }
+
+ //
+ // Return the operation status
+ //
+ DBG_EXIT_STATUS ( Status );
+ return Status;
+}
+
+
+/**
+ Process the work for the sockets.
+
+ @param [in] pTftpServer Address of the ::TSDT_TFTP_SERVER structure
+ @param [in] pIndex Address of an index into the pollfd array
+
+**/
+VOID
+PortWork (
+ IN TSDT_TFTP_SERVER * pTftpServer,
+ IN int * pIndex
+ )
+{
+ int Index;
+ TSDT_CONNECTION_CONTEXT * pContext;
+ struct pollfd * pTftpPort;
+ socklen_t RemoteAddressLength;
+ int revents;
+
+ DBG_ENTER ( );
+
+ //
+ // Locate the port
+ //
+ Index = *pIndex;
+ if ( -1 != Index ) {
+ pTftpPort = &pTftpServer->TftpPort[ *pIndex ];
+
+ //
+ // Handle input events
+ //
+ revents = pTftpPort->revents;
+ pTftpPort->revents = 0;
+ if ( 0 != ( revents & POLLRDNORM )) {
+ //
+ // Receive the message from the remote system
+ //
+ RemoteAddressLength = sizeof ( pTftpServer->RemoteAddress );
+ pTftpServer->RxBytes = recvfrom ( pTftpPort->fd,
+ &pTftpServer->RxBuffer[ 0 ],
+ sizeof ( pTftpServer->RxBuffer ),
+ 0,
+ (struct sockaddr *) &pTftpServer->RemoteAddress,
+ &RemoteAddressLength );
+ if ( -1 != pTftpServer->RxBytes ) {
+ if ( PcdGetBool ( Tftp_HighSpeed )) {
+ pTftpServer->RxTime = GetPerformanceCounter ( );
+ }
+ if ( AF_INET == pTftpServer->RemoteAddress.v4.sin_family ) {
+ DEBUG (( DEBUG_TFTP_PORT,
+ "Received %d bytes from %d.%d.%d.%d:%d\r\n",
+ pTftpServer->RxBytes,
+ pTftpServer->RemoteAddress.v4.sin_addr.s_addr & 0xff,
+ ( pTftpServer->RemoteAddress.v4.sin_addr.s_addr >> 8 ) & 0xff,
+ ( pTftpServer->RemoteAddress.v4.sin_addr.s_addr >> 16 ) & 0xff,
+ ( pTftpServer->RemoteAddress.v4.sin_addr.s_addr >> 24 ) & 0xff,
+ htons ( pTftpServer->RemoteAddress.v4.sin_port )));
+ }
+ else {
+ DEBUG (( DEBUG_TFTP_PORT,
+ "Received %d bytes from [%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]:%d\r\n",
+ pTftpServer->RxBytes,
+ pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 0 ],
+ pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 1 ],
+ pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 2 ],
+ pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 3 ],
+ pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 4 ],
+ pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 5 ],
+ pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 6 ],
+ pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 7 ],
+ pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 8 ],
+ pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 9 ],
+ pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 10 ],
+ pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 11 ],
+ pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 12 ],
+ pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 13 ],
+ pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 14 ],
+ pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 15 ],
+ htons ( pTftpServer->RemoteAddress.v6.sin6_port )));
+ }
+
+ //
+ // Lookup connection context using the remote system address and port
+ // to determine if an existing connection to this remote
+ // system exists
+ //
+ pContext = ContextFind ( pTftpServer );
+
+ //
+ // Process the received message
+ //
+ TftpProcessRequest ( pTftpServer, pContext, pTftpPort->fd );
+ }
+ else {
+ //
+ // Receive error on the TFTP server port
+ // Close the server socket
+ //
+ DEBUG (( DEBUG_ERROR,
+ "ERROR - Failed receive on TFTP server port, errno: 0x%08x\r\n",
+ errno ));
+ revents |= POLLHUP;
+ }
+ }
+
+ //
+ // Handle the close event
+ //
+ if ( 0 != ( revents & POLLHUP )) {
+ //
+ // Close the port
+ //
+ close ( pTftpPort->fd );
+ pTftpPort->fd = -1;
+ *pIndex = -1;
+ pTftpServer->Entries -= 1;
+ ASSERT ( 0 <= pTftpServer->Entries );
+ }
+ }
+
+ DBG_EXIT ( );
+}
+
+
+/**
+ Build and send an error packet
+
+ @param [in] pContext Address of a ::TSDT_CONNECTION_CONTEXT structure
+ @param [in] Error Error number for the packet
+ @param [in] pError Zero terminated error string address
+
+ @retval EFI_SUCCESS Message processed successfully
+
+**/
+EFI_STATUS
+SendError (
+ IN TSDT_CONNECTION_CONTEXT * pContext,
+ IN UINT16 Error,
+ IN UINT8 * pError
+ )
+{
+ UINT8 Character;
+ UINT8 * pBuffer;
+ TFTP_PACKET * pPacket;
+ EFI_STATUS Status;
+
+ DBG_ENTER ( );
+
+ //
+ // Build the error packet
+ //
+ pPacket = &pContext->ErrorPacket;
+ pBuffer = &pPacket->TxBuffer[ 0 ];
+ pBuffer[ 0 ] = 0;
+ pBuffer[ 1 ] = TFTP_OP_ERROR;
+ pBuffer[ 2 ] = (UINT8)( Error >> 8 );
+ pBuffer[ 3 ] = (UINT8)Error;
+
+ //
+ // Copy the zero terminated string into the buffer
+ //
+ pBuffer += 4;
+ do {
+ Character = *pError++;
+ *pBuffer++ = Character;
+ } while ( 0 != Character );
+
+ //
+ // Send the error message
+ //
+ pPacket->TxBytes = pBuffer - &pPacket->TxBuffer[ 0 ];
+ Status = PacketTx ( pContext, pPacket );
+
+ //
+ // Return the operation status
+ //
+ DBG_EXIT_STATUS ( Status );
+ return Status;
+}
+
+
+/**
+ Scan the list of sockets and process any pending work
+
+ @param [in] pTftpServer Address of the ::TSDT_TFTP_SERVER structure
+
+**/
+VOID
+SocketPoll (
+ IN TSDT_TFTP_SERVER * pTftpServer
+ )
+{
+ int FDCount;
+
+ DEBUG (( DEBUG_SOCKET_POLL, "Entering SocketPoll\r\n" ));
+
+ //
+ // Determine if any ports are active
+ //
+ if ( 0 != pTftpServer->Entries ) {
+ FDCount = poll ( &pTftpServer->TftpPort[ 0 ],
+ pTftpServer->Entries,
+ CLIENT_POLL_DELAY );
+ if ( 0 < FDCount ) {
+ //
+ // Process this port
+ //
+ PortWork ( pTftpServer, &pTftpServer->Udpv4Index );
+ PortWork ( pTftpServer, &pTftpServer->Udpv6Index );
+ }
+ }
+
+ DEBUG (( DEBUG_SOCKET_POLL, "Exiting SocketPoll\r\n" ));
+}
+
+
+/**
+ Process the ACK
+
+ @param [in] pTftpServer Address of the ::TSDT_TFTP_SERVER structure
+ @param [in] pContext Connection context structure address
+
+ @retval TRUE if the context should be closed
+
+**/
+BOOLEAN
+TftpAck (
+ IN TSDT_TFTP_SERVER * pTftpServer,
+ IN TSDT_CONNECTION_CONTEXT * pContext
+ )
+{
+ INTN AckNumber;
+ BOOLEAN bCloseContext;
+ UINT16 BlockNumber;
+ UINT8 * pBuffer;
+ TFTP_PACKET * pPacket;
+ EFI_STATUS Status;
+
+ DBG_ENTER ( );
+
+ //
+ // Use break instead of goto
+ //
+ bCloseContext = FALSE;
+ for ( ; ; ) {
+ //
+ // Validate the parameters
+ //
+ if ( NULL == pContext ) {
+ if ( AF_INET == pTftpServer->RemoteAddress.v4.sin_family ) {
+ DEBUG (( DEBUG_ERROR,
+ "ERROR - File not open for %d.%d.%d.%d:%d\r\n",
+ (UINT8)pTftpServer->RemoteAddress.v4.sin_addr.s_addr,
+ (UINT8)( pTftpServer->RemoteAddress.v4.sin_addr.s_addr >> 8 ),
+ (UINT8)( pTftpServer->RemoteAddress.v4.sin_addr.s_addr >> 16 ),
+ (UINT8)( pTftpServer->RemoteAddress.v4.sin_addr.s_addr >> 24 ),
+ htons ( pTftpServer->RemoteAddress.v4.sin_port )));
+ }
+ else {
+ DEBUG (( DEBUG_ERROR,
+ "ERROR - File not open for [%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]:%d\r\n",
+ pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 0 ],
+ pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 1 ],
+ pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 2 ],
+ pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 3 ],
+ pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 4 ],
+ pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 5 ],
+ pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 6 ],
+ pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 7 ],
+ pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 8 ],
+ pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 9 ],
+ pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 10 ],
+ pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 11 ],
+ pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 12 ],
+ pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 13 ],
+ pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 14 ],
+ pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 15 ],
+ htons ( pTftpServer->RemoteAddress.v6.sin6_port )));
+ }
+ break;
+ }
+
+ //
+ // Verify that the ACK was expected
+ //
+ pPacket = pContext->pTxHead;
+ if ( NULL == pPacket ) {
+ //
+ // ACK not expected!
+ //
+ DEBUG (( DEBUG_ERROR,
+ "ERROR - Expecting data not ACKs for pContext 0x%08x\r\n",
+ pContext ));
+ break;
+ }
+
+ //
+ // Get the ACKed block number
+ //
+ pBuffer = &pTftpServer->RxBuffer[ 0 ];
+ BlockNumber = HTONS ( *(UINT16 *)&pBuffer[ 2 ]);
+
+ //
+ // Determine if this is the correct ACK
+ //
+ DEBUG (( DEBUG_TFTP_ACK,
+ "ACK for block 0x%04x received\r\n",
+ BlockNumber ));
+ AckNumber = BlockNumber - pPacket->BlockNumber;
+ if (( 0 > AckNumber ) || ( AckNumber >= (INTN)pContext->PacketsInWindow )){
+ DEBUG (( DEBUG_WARN | DEBUG_TFTP_ACK,
+ "WARNING - Expecting ACK 0x%0x4 not received ACK 0x%08x\r\n",
+ pPacket->BlockNumber,
+ BlockNumber ));
+ break;
+ }
+
+ //
+ // Release the ACKed packets
+ //
+ do {
+ //
+ // Remove the packet from the transmit list and window
+ //
+ pPacket = PacketRemove ( pContext );
+
+ //
+ // Get the block number of this packet
+ //
+ AckNumber = pPacket->BlockNumber;
+
+ //
+ // Increase the size of the transmit window
+ //
+ if ( PcdGetBool ( Tftp_HighSpeed )
+ && ( AckNumber == BlockNumber )) {
+ WindowAck ( pTftpServer, pContext, pPacket );
+ }
+
+ //
+ // Free this packet
+ //
+ PacketFree ( pContext, pPacket );
+ } while (( NULL != pContext->pTxHead ) && ( AckNumber != BlockNumber ));
+
+ //
+ // Fill the window with packets
+ //
+ pPacket = pContext->pTxHead;
+ while (( NULL != pPacket )
+ && ( pContext->PacketsInWindow < pContext->WindowSize )
+ && ( !bCloseContext )) {
+ Status = PacketTx ( pContext, pPacket );
+ bCloseContext = (BOOLEAN)( EFI_ERROR ( Status ));
+ pPacket = pPacket->pNext;
+ }
+
+ //
+ // Get more packets ready for transmission
+ //
+ PacketFill ( pContext );
+
+ //
+ // Close the context when the last packet is ACKed
+ //
+ if ( 0 == pContext->PacketsInWindow ) {
+ bCloseContext = TRUE;
+
+ //
+ // Display the bandwidth
+ //
+ if ( PcdGetBool ( Tftp_Bandwidth )) {
+ UINT64 Bandwidth;
+ UINT64 DeltaTime;
+ UINT64 NanoSeconds;
+ UINT32 Value;
+
+ //
+ // Compute the download time
+ //
+ DeltaTime = GetPerformanceCounter ( );
+ if ( pTftpServer->Time2 > pTftpServer->Time1 ) {
+ DeltaTime = DeltaTime - pContext->TimeStart;
+ }
+ else {
+ DeltaTime = pContext->TimeStart - DeltaTime;
+ }
+ NanoSeconds = GetTimeInNanoSecond ( DeltaTime );
+ Bandwidth = pContext->LengthInBytes;
+ DEBUG (( DEBUG_WINDOW,
+ "File Length %Ld, Transfer Time: %d.%03d Sec\r\n",
+ Bandwidth,
+ DivU64x32 ( NanoSeconds, 1000 * 1000 * 1000 ),
+ ((UINT32)DivU64x32 ( NanoSeconds, 1000 * 1000 )) % 1000 ));
+
+ //
+ // Display the round trip time
+ //
+ Bandwidth = MultU64x32 ( Bandwidth, 8 * 1000 * 1000 );
+ Bandwidth /= NanoSeconds;
+ if ( 1000 > Bandwidth ) {
+ Value = (UINT32)Bandwidth;
+ Print ( L"Bandwidth: %d Kbits/Sec\r\n",
+ Value );
+ }
+ else if (( 1000 * 1000 ) > Bandwidth ) {
+ Value = (UINT32)Bandwidth;
+ Print ( L"Bandwidth: %d.%03d Mbits/Sec\r\n",
+ Value / 1000,
+ Value % 1000 );
+ }
+ else {
+ Value = (UINT32)DivU64x32 ( Bandwidth, 1000 );
+ Print ( L"Bandwidth: %d.%03d Gbits/Sec\r\n",
+ Value / 1000,
+ Value % 1000 );
+ }
+ }
+ }
+ break;
+ }
+
+ //
+ // Return the operation status
+ //
+ DBG_EXIT ( );
+ return bCloseContext;
+}
+
+
+/**
+ Get the next TFTP option
+
+ @param [in] pOption Address of a zero terminated option string
+ @param [in] pEnd End of buffer address
+ @param [in] ppNextOption Address to receive the address of the next
+ zero terminated option string
+
+ @retval EFI_SUCCESS Message processed successfully
+
+**/
+EFI_STATUS
+TftpOptionGet (
+ IN UINT8 * pOption,
+ IN UINT8 * pEnd,
+ IN UINT8 ** ppNextOption
+ )
+{
+ UINT8 * pNextOption;
+ EFI_STATUS Status;
+
+ //
+ // Locate the end of the option
+ //
+ pNextOption = pOption;
+ while (( pEnd > pNextOption ) && ( 0 != *pNextOption )) {
+ pNextOption += 1;
+ }
+ if ( pEnd <= pNextOption ) {
+ //
+ // Error - end of buffer reached
+ //
+ DEBUG (( DEBUG_ERROR | DEBUG_TFTP_REQUEST,
+ "ERROR - Option without zero termination received!\r\n" ));
+ Status = EFI_INVALID_PARAMETER;
+ }
+ else {
+ //
+ // Zero terminated option found
+ //
+ pNextOption += 1;
+
+ //
+ // Display the zero terminated ASCII option string
+ //
+ DEBUG (( DEBUG_TFTP_REQUEST,
+ "Option: %a\r\n",
+ pOption ));
+ Status = EFI_SUCCESS;
+ }
+
+ //
+ // Return the next option address
+ //
+ *ppNextOption = pNextOption;
+
+ //
+ // Return the operation status
+ //
+ return Status;
+}
+
+
+/**
+ Place an option value into the option acknowledgement
+
+ @param [in] pOack Option acknowledgement address
+ @param [in] Value Value to translate into ASCII decimal
+
+ @return Option acknowledgement address
+
+**/
+UINT8 *
+TftpOptionSet (
+ IN UINT8 * pOack,
+ IN UINT64 Value
+ )
+{
+ UINT64 NextValue;
+
+ //
+ // Determine the next value
+ //
+ NextValue = Value / 10;
+
+ //
+ // Supress leading zeros
+ //
+ if ( 0 != NextValue ) {
+ pOack = TftpOptionSet ( pOack, NextValue );
+ }
+
+ //
+ // Output this digit
+ //
+ *pOack++ = (UINT8)( Value - ( NextValue * 10 ) + '0' );
+
+ //
+ // Return the next option acknowledgement location
+ //
+ return pOack;
+}
+
+
+/**
+ Process the TFTP request
+
+ @param [in] pContext Address of a ::TSDT_CONNECTION_CONTEXT structure
+ @param [in] pOption Address of the first zero terminated option string
+ @param [in] pEnd End of buffer address
+
+**/
+VOID
+TftpOptions (
+ IN TSDT_CONNECTION_CONTEXT * pContext,
+ IN UINT8 * pOption,
+ IN UINT8 * pEnd
+ )
+{
+ UINT8 * pNextOption;
+ UINT8 * pOack;
+ TFTP_PACKET * pPacket;
+ UINT8 * pTemp;
+ UINT8 * pValue;
+ EFI_STATUS Status;
+ INT32 Value;
+
+ //
+ // Get a packet
+ //
+ pPacket = PacketGet ( pContext );
+
+ //
+ // Start the OACK packet
+ // Let the OACK handle the parsing errors
+ // See http://tools.ietf.org/html/rfc2347
+ //
+ pOack = &pPacket->TxBuffer[ 0 ];
+ *pOack++ = 0;
+ *pOack++ = TFTP_OP_OACK;
+ pPacket->TxBytes = 2;
+ pPacket->BlockNumber = 0;
+
+ //
+ // Walk the list of options
+ //
+ do {
+ //
+ // Get the next option, skip junk at end of message
+ //
+ Status = TftpOptionGet ( pOption, pEnd, &pNextOption );
+ if ( !EFI_ERROR ( Status )) {
+ //
+ // Process the option
+ //
+
+ //
+ // blksize - See http://tools.ietf.org/html/rfc2348
+ //
+ pValue = pNextOption;
+ if ( 0 == strcasecmp ((char *)pOption, "blksize" )) {
+ //
+ // Get the value
+ //
+ Status = TftpOptionGet ( pValue, pEnd, &pNextOption );
+ if ( !EFI_ERROR ( Status )) {
+ //
+ // Validate the block size, skip non-numeric block sizes
+ //
+ Status = TftpOptionValue ( pValue, &Value );
+ if ( !EFI_ERROR ( Status )) {
+ //
+ // Propose a smaller block size if necessary
+ //
+ if ( Value > TFTP_MAX_BLOCK_SIZE ) {
+ Value = TFTP_MAX_BLOCK_SIZE;
+ }
+
+ //
+ // Set the new block size
+ //
+ pContext->BlockSize = Value;
+ DEBUG (( DEBUG_TFTP_REQUEST,
+ "Using block size of %d bytes\r\n",
+ pContext->BlockSize ));
+
+ //
+ // Update the OACK
+ //
+ pTemp = pOack;
+ *pOack++ = 'b';
+ *pOack++ = 'l';
+ *pOack++ = 'k';
+ *pOack++ = 's';
+ *pOack++ = 'i';
+ *pOack++ = 'z';
+ *pOack++ = 'e';
+ *pOack++ = 0;
+ pOack = TftpOptionSet ( pOack, pContext->BlockSize );
+ *pOack++ = 0;
+ pPacket->TxBytes += pOack - pTemp;
+ }
+ }
+ }
+
+ //
+ // timeout - See http://tools.ietf.org/html/rfc2349
+ //
+ else if ( 0 == strcasecmp ((char *)pOption, "timeout" )) {
+ //
+ // Get the value
+ //
+ Status = TftpOptionGet ( pValue, pEnd, &pNextOption );
+ if ( !EFI_ERROR ( Status )) {
+ Status = TftpOptionValue ( pValue, &Value );
+ if ( !EFI_ERROR ( Status )) {
+ //
+ // Set the timeout value
+ //
+ pContext->MaxTimeout = Value;
+ DEBUG (( DEBUG_TFTP_REQUEST,
+ "Using timeout of %d seconds\r\n",
+ pContext->MaxTimeout ));
+
+ //
+ // Update the OACK
+ //
+ pTemp = pOack;
+ *pOack++ = 't';
+ *pOack++ = 'i';
+ *pOack++ = 'm';
+ *pOack++ = 'e';
+ *pOack++ = 'o';
+ *pOack++ = 'u';
+ *pOack++ = 't';
+ *pOack++ = 0;
+ pOack = TftpOptionSet ( pOack, pContext->MaxTimeout );
+ *pOack++ = 0;
+ pPacket->TxBytes += pOack - pTemp;
+ }
+ }
+ }
+
+ //
+ // tsize - See http://tools.ietf.org/html/rfc2349
+ //
+ else if ( 0 == strcasecmp ((char *)pOption, "tsize" )) {
+ //
+ // Get the value
+ //
+ Status = TftpOptionGet ( pValue, pEnd, &pNextOption );
+ if ( !EFI_ERROR ( Status )) {
+ Status = TftpOptionValue ( pValue, &Value );
+ if ( !EFI_ERROR ( Status )) {
+ //
+ // Return the file size
+ //
+ DEBUG (( DEBUG_TFTP_REQUEST,
+ "Returning file size of %Ld bytes\r\n",
+ pContext->LengthInBytes ));
+
+ //
+ // Update the OACK
+ //
+ pTemp = pOack;
+ *pOack++ = 't';
+ *pOack++ = 's';
+ *pOack++ = 'i';
+ *pOack++ = 'z';
+ *pOack++ = 'e';
+ *pOack++ = 0;
+ pOack = TftpOptionSet ( pOack, pContext->LengthInBytes );
+ *pOack++ = 0;
+ pPacket->TxBytes += pOack - pTemp;
+ }
+ }
+ }
+ else {
+ //
+ // Unknown option - Ignore it
+ //
+ DEBUG (( DEBUG_WARN | DEBUG_TFTP_REQUEST,
+ "WARNING - Skipping unknown option: %a\r\n",
+ pOption ));
+ }
+ }
+
+ //
+ // Set the next option
+ //
+ pOption = pNextOption;
+ } while ( pEnd > pOption );
+
+ //
+ // Transmit the OACK if necessary
+ //
+ if ( 2 < pPacket->TxBytes ) {
+ PacketQueue ( pContext, pPacket );
+ }
+ else {
+ PacketFree ( pContext, pPacket );
+ }
+}
+
+
+/**
+ Process the TFTP request
+
+ @param [in] pOption Address of the first zero terminated option string
+ @param [in] pValue Address to receive the value
+
+ @retval EFI_SUCCESS Option translated into a value
+
+**/
+EFI_STATUS
+TftpOptionValue (
+ IN UINT8 * pOption,
+ IN INT32 * pValue
+ )
+{
+ UINT8 Digit;
+ EFI_STATUS Status;
+ INT32 Value;
+
+ //
+ // Assume success
+ //
+ Status = EFI_SUCCESS;
+
+ //
+ // Walk the characters in the option
+ //
+ Value = 0;
+ while ( 0 != *pOption ) {
+ //
+ // Convert the next digit to binary
+ //
+ Digit = *pOption++;
+ if (( '0' <= Digit ) && ( '9' >= Digit )) {
+ Value *= 10;
+ Value += Digit - '0';
+ }
+ else {
+ DEBUG (( DEBUG_ERROR | DEBUG_TFTP_REQUEST,
+ "ERROR - Invalid character '0x%02x' in the value\r\n",
+ Digit ));
+ Status = EFI_INVALID_PARAMETER;
+ break;
+ }
+ }
+
+ //
+ // Return the value
+ //
+ *pValue = Value;
+
+ //
+ // Return the conversion status
+ //
+ return Status;
+}
+
+
+/**
+ Process the TFTP request
+
+ @param [in] pTftpServer Address of the ::TSDT_TFTP_SERVER structure
+ @param [in] pContext Address of a ::TSDT_CONNECTION_CONTEXT structure
+ @param [in] SocketFd Socket file descriptor
+
+**/
+VOID
+TftpProcessRequest (
+ IN TSDT_TFTP_SERVER * pTftpServer,
+ IN TSDT_CONNECTION_CONTEXT * pContext,
+ IN int SocketFd
+ )
+{
+ BOOLEAN bCloseContext;
+ UINT16 Opcode;
+
+ DBG_ENTER ( );
+
+ //
+ // Get the opcode
+ //
+ Opcode = HTONS ( *(UINT16 *)&pTftpServer->RxBuffer[ 0 ]);
+ DEBUG (( DEBUG_TFTP_REQUEST,
+ "TFTP Opcode: 0x%08x\r\n",
+ Opcode ));
+
+ //
+ // Validate the parameters
+ //
+ bCloseContext = FALSE;
+ switch ( Opcode ) {
+ default:
+ DEBUG (( DEBUG_TFTP_REQUEST,
+ "ERROR - Unknown TFTP opcode: %d\r\n",
+ Opcode ));
+ break;
+
+ case TFTP_OP_ACK:
+ bCloseContext = TftpAck ( pTftpServer, pContext );
+ break;
+
+ case TFTP_OP_READ_REQUEST:
+ bCloseContext = TftpRead ( pTftpServer, pContext, SocketFd );
+ break;
+
+
+
+
+ case TFTP_OP_DATA:
+ if ( NULL == pContext ) {
+ if ( AF_INET == pTftpServer->RemoteAddress.v4.sin_family ) {
+ DEBUG (( DEBUG_ERROR,
+ "ERROR - File not open for %d.%d.%d.%d:%d\r\n",
+ (UINT8)pTftpServer->RemoteAddress.v4.sin_addr.s_addr,
+ (UINT8)( pTftpServer->RemoteAddress.v4.sin_addr.s_addr >> 8 ),
+ (UINT8)( pTftpServer->RemoteAddress.v4.sin_addr.s_addr >> 16 ),
+ (UINT8)( pTftpServer->RemoteAddress.v4.sin_addr.s_addr >> 24 ),
+ htons ( pTftpServer->RemoteAddress.v4.sin_port )));
+ }
+ else {
+ DEBUG (( DEBUG_ERROR,
+ "ERROR - File not open for [%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]:%d\r\n",
+ pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 0 ],
+ pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 1 ],
+ pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 2 ],
+ pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 3 ],
+ pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 4 ],
+ pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 5 ],
+ pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 6 ],
+ pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 7 ],
+ pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 8 ],
+ pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 9 ],
+ pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 10 ],
+ pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 11 ],
+ pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 12 ],
+ pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 13 ],
+ pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 14 ],
+ pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 15 ],
+ htons ( pTftpServer->RemoteAddress.v6.sin6_port )));
+ }
+ break;
+ }
+ if ( 0 != pContext->PacketsInWindow ) {
+ DEBUG (( DEBUG_ERROR,
+ "ERROR - Expecting ACKs not data for pContext 0x%08x\r\n",
+ pContext ));
+ break;
+ }
+ if ( pTftpServer->RxBytes > (ssize_t)( pContext->BlockSize + 2 + 2 )) {
+ DEBUG (( DEBUG_ERROR,
+ "ERROR - Receive data length of %d > %d bytes (maximum block size) for pContext 0x%08x\r\n",
+ pTftpServer->RxBytes - 2 - 2,
+ pContext->BlockSize,
+ pContext ));
+ break;
+ }
+ break;
+
+ case TFTP_OP_ERROR:
+ if ( NULL == pContext ) {
+ if ( AF_INET == pTftpServer->RemoteAddress.v4.sin_family ) {
+ DEBUG (( DEBUG_ERROR,
+ "ERROR - File not open for %d.%d.%d.%d:%d\r\n",
+ (UINT8)pTftpServer->RemoteAddress.v4.sin_addr.s_addr,
+ (UINT8)( pTftpServer->RemoteAddress.v4.sin_addr.s_addr >> 8 ),
+ (UINT8)( pTftpServer->RemoteAddress.v4.sin_addr.s_addr >> 16 ),
+ (UINT8)( pTftpServer->RemoteAddress.v4.sin_addr.s_addr >> 24 ),
+ htons ( pTftpServer->RemoteAddress.v4.sin_port )));
+ }
+ else {
+ DEBUG (( DEBUG_ERROR,
+ "ERROR - File not open for [%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]:%d\r\n",
+ pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 0 ],
+ pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 1 ],
+ pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 2 ],
+ pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 3 ],
+ pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 4 ],
+ pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 5 ],
+ pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 6 ],
+ pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 7 ],
+ pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 8 ],
+ pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 9 ],
+ pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 10 ],
+ pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 11 ],
+ pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 12 ],
+ pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 13 ],
+ pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 14 ],
+ pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 15 ],
+ htons ( pTftpServer->RemoteAddress.v6.sin6_port )));
+ }
+ }
+ break;
+ }
+
+ //
+ // Determine if the context should be closed
+ //
+ if ( bCloseContext ) {
+ ContextRemove ( pTftpServer, pContext );
+ }
+
+ DBG_EXIT ( );
+}
+
+
+/**
+ Process the read request
+
+ @param [in] pTftpServer Address of the ::TSDT_TFTP_SERVER structure
+ @param [in] pContext Address of a ::TSDT_CONNECTION_CONTEXT structure
+ @param [in] SocketFd Socket file descriptor
+
+ @retval TRUE if the context should be closed
+
+**/
+BOOLEAN
+TftpRead (
+ IN TSDT_TFTP_SERVER * pTftpServer,
+ IN TSDT_CONNECTION_CONTEXT * pContext,
+ IN int SocketFd
+ )
+{
+ BOOLEAN bCloseContext;
+ struct stat FileStatus;
+ UINT8 * pBuffer;
+ UINT8 * pEnd;
+ UINT8 * pFileName;
+ UINT8 * pMode;
+ UINT8 * pOption;
+ CHAR8 * pReadMode;
+ UINT64 TimeStart;
+
+ DBG_ENTER ( );
+
+ //
+ // Log the receive time
+ //
+ TimeStart = 0;
+ if ( PcdGetBool ( Tftp_Bandwidth )) {
+ TimeStart = GetPerformanceCounter ( );
+ }
+
+ //
+ // Close the context if necessary
+ //
+ bCloseContext = FALSE;
+ if ( NULL != pContext ) {
+ ContextRemove ( pTftpServer, pContext );
+ }
+
+ //
+ // Use break instead of goto
+ //
+ for ( ; ; ) {
+ //
+ // Create the connection context
+ //
+ pContext = ContextAdd ( pTftpServer, SocketFd );
+ if ( NULL == pContext ) {
+ break;
+ }
+
+ //
+ // Set the start time
+ //
+ if ( PcdGetBool ( Tftp_Bandwidth )) {
+ pContext->TimeStart = TimeStart;
+ }
+
+ //
+ // Locate the mode
+ //
+ pBuffer = &pTftpServer->RxBuffer[ 0 ];
+ pEnd = &pBuffer[ pTftpServer->RxBytes ];
+ pFileName = &pBuffer[ 2 ];
+ pMode = pFileName;
+ while (( pEnd > pMode ) && ( 0 != *pMode )) {
+ pMode += 1;
+ }
+ if ( pEnd <= pMode ) {
+ //
+ // Mode not found
+ //
+ DEBUG (( DEBUG_ERROR | DEBUG_RX,
+ "ERROR - File mode not found\r\n" ));
+ //
+ // Tell the client of the error
+ //
+ SendError ( pContext,
+ TFTP_ERROR_SEE_MSG,
+ (UINT8 *)"File open mode not found" );
+ break;
+ }
+ pMode += 1;
+ DEBUG (( DEBUG_TFTP_REQUEST,
+ "TFTP - FileName: %a\r\n",
+ pFileName ));
+
+ //
+ // Locate the options
+ //
+ pOption = pMode;
+ while (( pEnd > pOption ) && ( 0 != *pOption )) {
+ pOption += 1;
+ }
+ if ( pEnd <= pOption ) {
+ //
+ // End of mode not found
+ //
+ DEBUG (( DEBUG_ERROR | DEBUG_RX,
+ "ERROR - File mode not valid\r\n" ));
+ //
+ // Tell the client of the error
+ //
+ SendError ( pContext,
+ TFTP_ERROR_SEE_MSG,
+ (UINT8 *)"File open mode not valid" );
+ break;
+ }
+ pOption += 1;
+ DEBUG (( DEBUG_TFTP_REQUEST,
+ "TFTP - Mode: %a\r\n",
+ pMode ));
+
+ //
+ // Verify the mode is supported
+ //
+ pReadMode = "r";
+ if ( 0 == strcasecmp ((char *)pMode, "octet" )) {
+ //
+ // Read the file as binary input
+ //
+ pReadMode = "rb";
+ }
+
+ //
+ // Determine the file length
+ //
+ pContext->File = fopen ((const char *)pFileName, pReadMode );
+ if (( NULL == pContext->File )
+ || ( -1 == stat ((const char *)pFileName, &FileStatus ))) {
+ //
+ // File not found
+ //
+ DEBUG (( DEBUG_ERROR | DEBUG_TFTP_REQUEST,
+ ( NULL == pContext->File )
+ ? "ERROR - File not found!\r\n"
+ : "ERROR - Unable to determine file %a size!\r\n",
+ pFileName ));
+
+ //
+ // Tell the client of the error
+ //
+ SendError ( pContext,
+ TFTP_ERROR_NOT_FOUND,
+ (UINT8 *)"File not found" );
+ break;
+ }
+ pContext->LengthInBytes = FileStatus.st_size;
+ pContext->BytesRemaining = pContext->LengthInBytes;
+ pContext->BytesToSend = pContext->LengthInBytes;
+
+ //
+ // Display the file size
+ //
+ DEBUG_CODE_BEGIN ( );
+ UINT32 Value;
+
+ if ( 1024 > pContext->LengthInBytes ) {
+ Value = (UINT32)pContext->LengthInBytes;
+ DEBUG (( DEBUG_FILE_BUFFER,
+ "%a size: %d Bytes\r\n",
+ pFileName,
+ Value ));
+ }
+ else if (( 1024 * 1024 ) > pContext->LengthInBytes ) {
+ Value = (UINT32)pContext->LengthInBytes;
+ DEBUG (( DEBUG_FILE_BUFFER,
+ "%a size: %d.%03d KiBytes (%Ld Bytes)\r\n",
+ pFileName,
+ Value / 1024,
+ (( Value % 1024 ) * 1000 ) / 1024,
+ pContext->LengthInBytes ));
+ }
+ else if (( 1024 * 1024 * 1024 ) > pContext->LengthInBytes ) {
+ Value = (UINT32)DivU64x32 ( pContext->LengthInBytes, 1024 );
+ DEBUG (( DEBUG_FILE_BUFFER,
+ "%a size: %d.%03d MiBytes (%Ld Bytes)\r\n",
+ pFileName,
+ Value / 1024,
+ (( Value % 1024 ) * 1000 ) / 1024,
+ pContext->LengthInBytes ));
+ }
+ else {
+ Value = (UINT32)DivU64x32 ( pContext->LengthInBytes, 1024 * 1024 );
+ DEBUG (( DEBUG_FILE_BUFFER,
+ "%a size: %d.%03d GiBytes (%Ld Bytes)\r\n",
+ pFileName,
+ Value / 1024,
+ (( Value % 1024 ) * 1000 ) / 1024,
+ pContext->LengthInBytes ));
+ }
+ DEBUG_CODE_END ( );
+
+ //
+ // Process the options
+ //
+ if ( pEnd > pOption ) {
+ TftpOptions ( pContext, pOption, pEnd );
+ }
+ else {
+ //
+ // Skip the open ACK
+ //
+ pContext->BlockNumber = 1;
+ }
+
+ //
+ // Send the first packet (OACK or data block)
+ //
+ bCloseContext = PacketFill ( pContext );
+ break;
+ }
+
+ //
+ // Return the close status
+ //
+ DBG_EXIT ( );
+ return bCloseContext;
+}
+
+
+/**
+ Create the port for the TFTP server
+
+ This routine polls the network layer to create the TFTP port for the
+ TFTP 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.
+
+ @param [in] pTftpServer Address of the ::TSDT_TFTP_SERVER structure
+ @param [in] AddressFamily The address family to use for the conection.
+ @param [in] pIndex Address of the index into the port array
+
+**/
+VOID
+TftpServerSocket (
+ IN TSDT_TFTP_SERVER * pTftpServer,
+ IN sa_family_t AddressFamily,
+ IN int * pIndex
+ )
+{
+ int SocketStatus;
+ struct pollfd * pTftpPort;
+ UINT16 TftpPort;
+ union {
+ struct sockaddr_in v4;
+ struct sockaddr_in6 v6;
+ } TftpServerAddress;
+
+ DEBUG (( DEBUG_SERVER_TIMER, "Entering TftpServerListen\r\n" ));
+
+ //
+ // Determine if the socket is already initialized
+ //
+ if ( -1 == *pIndex ) {
+ //
+ // Attempt to create the socket for the TFTP server
+ //
+ pTftpPort = &pTftpServer->TftpPort[ pTftpServer->Entries ];
+ pTftpPort->fd = socket ( AddressFamily,
+ SOCK_DGRAM,
+ IPPROTO_UDP );
+ if ( -1 != pTftpPort->fd ) {
+ //
+ // Initialize the poll structure
+ //
+ pTftpPort->events = POLLRDNORM | POLLHUP;
+ pTftpPort->revents = 0;
+
+ //
+ // Set the socket address
+ //
+ TftpPort = 69;
+ ZeroMem ( &TftpServerAddress, sizeof ( TftpServerAddress ));
+ TftpServerAddress.v4.sin_port = htons ( TftpPort );
+ if ( AF_INET == AddressFamily ) {
+ TftpServerAddress.v4.sin_len = sizeof ( TftpServerAddress.v4 );
+ TftpServerAddress.v4.sin_family = AF_INET;
+ }
+ else {
+ TftpServerAddress.v6.sin6_len = sizeof ( TftpServerAddress.v6 );
+ TftpServerAddress.v6.sin6_family = AF_INET6;
+ }
+
+ //
+ // Bind the socket to the TFTP port
+ //
+ SocketStatus = bind ( pTftpPort->fd,
+ (struct sockaddr *) &TftpServerAddress,
+ TftpServerAddress.v6.sin6_len );
+ if ( -1 != SocketStatus ) {
+ DEBUG (( DEBUG_TFTP_PORT,
+ "0x%08x: Socket bound to port %d\r\n",
+ pTftpPort->fd,
+ TftpPort ));
+
+ //
+ // Account for this connection
+ //
+ *pIndex = pTftpServer->Entries;
+ pTftpServer->Entries += 1;
+ ASSERT ( DIM ( pTftpServer->TftpPort ) >= pTftpServer->Entries );
+ }
+
+ //
+ // Release the socket if necessary
+ //
+ if ( -1 == SocketStatus ) {
+ close ( pTftpPort->fd );
+ pTftpPort->fd = -1;
+ }
+ }
+ }
+
+ DEBUG (( DEBUG_SERVER_TIMER, "Exiting TftpServerListen\r\n" ));
+}
+
+
+/**
+ Update the window due to the ACK
+
+ @param [in] pTftpServer Address of the ::TSDT_TFTP_SERVER structure
+ @param [in] pContext Address of a ::TSDT_CONNECTION_CONTEXT structure
+ @param [in] pPacket Address of a ::TFTP_PACKET structure
+
+**/
+VOID
+WindowAck (
+ IN TSDT_TFTP_SERVER * pTftpServer,
+ IN TSDT_CONNECTION_CONTEXT * pContext,
+ IN TFTP_PACKET * pPacket
+ )
+{
+ if ( PcdGetBool ( Tftp_HighSpeed )) {
+ UINT64 DeltaTime;
+ UINT64 NanoSeconds;
+
+ DBG_ENTER ( );
+
+ //
+ // Compute the round trip time
+ //
+ if ( pTftpServer->Time2 > pTftpServer->Time1 ) {
+ DeltaTime = pTftpServer->RxTime - pPacket->TxTime;
+ }
+ else {
+ DeltaTime = pPacket->TxTime - pTftpServer->RxTime;
+ }
+
+ //
+ // Adjust the round trip time
+ //
+ NanoSeconds = GetTimeInNanoSecond ( DeltaTime );
+ DeltaTime = RShiftU64 ( pContext->Rtt2x, ACK_SHIFT );
+ pContext->Rtt2x += NanoSeconds + NanoSeconds - DeltaTime;
+ if ( pContext->Rtt2x > pContext->MaxTimeout ) {
+ pContext->Rtt2x = pContext->MaxTimeout;
+ }
+
+ //
+ // Account for the ACK
+ //
+ if ( pContext->WindowSize < MAX_PACKETS ) {
+ pContext->AckCount -= 1;
+ if ( 0 == pContext->AckCount ) {
+ //
+ // Increase the window
+ //
+ pContext->WindowSize += 1;
+
+ //
+ // Set the ACK count
+ //
+ if ( pContext->WindowSize < pContext->Threshold ) {
+ pContext->AckCount = pContext->WindowSize * PcdGet32 ( Tftp_AckMultiplier );
+ }
+ else {
+ pContext->AckCount = PcdGet32 ( Tftp_AckLogBase ) << pContext->WindowSize;
+ }
+
+ //
+ // Display the round trip time
+ //
+ DEBUG_CODE_BEGIN ( );
+ UINT32 Value;
+
+ DeltaTime = RShiftU64 ( pContext->Rtt2x, 1 );
+ if ( 1000 > DeltaTime ) {
+ DEBUG (( DEBUG_WINDOW,
+ "WindowSize: %d, Threshold: %d, AckCount: %4d, RTT: %Ld nSec\r\n",
+ pContext->WindowSize,
+ pContext->Threshold,
+ pContext->AckCount,
+ DeltaTime ));
+ }
+ else if (( 1000 * 1000 ) > DeltaTime ) {
+ Value = (UINT32)DeltaTime;
+ DEBUG (( DEBUG_WINDOW,
+ "WindowSize: %d, Threshold: %d, AckCount: %4d, RTT: %d.%03d uSec\r\n",
+ pContext->WindowSize,
+ pContext->Threshold,
+ pContext->AckCount,
+ Value / 1000,
+ Value % 1000 ));
+ }
+ else if (( 1000 * 1000 * 1000 ) > DeltaTime ) {
+ Value = (UINT32)DivU64x32 ( DeltaTime, 1000 );
+ DEBUG (( DEBUG_WINDOW,
+ "WindowSize: %d, Threshold: %d, AckCount: %4d, RTT: %d.%03d mSec\r\n",
+ pContext->WindowSize,
+ pContext->Threshold,
+ pContext->AckCount,
+ Value / 1000,
+ Value % 1000 ));
+ }
+ else {
+ Value = (UINT32)DivU64x32 ( DeltaTime, 1000 * 1000 );
+ DEBUG (( DEBUG_WINDOW,
+ "WindowSize: %d, Threshold: %d, AckCount: %4d, RTT: %d.%03d Sec\r\n",
+ pContext->WindowSize,
+ pContext->Threshold,
+ pContext->AckCount,
+ Value / 1000,
+ Value % 1000 ));
+ }
+ DEBUG_CODE_END ( );
+ }
+ }
+
+ DBG_EXIT ( );
+ }
+}
+
+
+/**
+ A timeout has occurred, close the window
+
+ @param [in] pContext Address of a ::TSDT_CONNECTION_CONTEXT structure
+
+**/
+VOID
+WindowTimeout (
+ IN TSDT_CONNECTION_CONTEXT * pContext
+ )
+{
+ if ( PcdGetBool ( Tftp_HighSpeed )) {
+ TFTP_PACKET * pPacket;
+
+ DBG_ENTER ( );
+
+ //
+ // Set the threshold at half the previous window size
+ //
+ pContext->Threshold = ( pContext->WindowSize + 1 ) >> 1;
+
+ //
+ // Close the transmit window
+ //
+ pContext->WindowSize = 1;
+ pContext->PacketsInWindow = 0;
+
+ //
+ // Double the round trip time
+ //
+ pContext->Rtt2x = LShiftU64 ( pContext->Rtt2x, 1 );
+ if ( pContext->Rtt2x > pContext->MaxTimeout ) {
+ pContext->Rtt2x = pContext->MaxTimeout;
+ }
+
+ //
+ // Set the ACK count
+ //
+ if ( pContext->WindowSize < pContext->Threshold ) {
+ pContext->AckCount = pContext->WindowSize * PcdGet32 ( Tftp_AckMultiplier );
+ }
+ else {
+ pContext->AckCount = PcdGet32 ( Tftp_AckLogBase ) << pContext->WindowSize;
+ }
+
+ //
+ // Display the round trip time
+ //
+ DEBUG_CODE_BEGIN ( );
+ UINT64 DeltaTime;
+ UINT32 Value;
+
+ DeltaTime = RShiftU64 ( pContext->Rtt2x, 1 );
+ if ( 1000 > DeltaTime ) {
+ DEBUG (( DEBUG_WINDOW,
+ "WindowSize: %d, Threshold: %d, AckCount: %4d, RTT: %Ld nSec\r\n",
+ pContext->WindowSize,
+ pContext->Threshold,
+ pContext->AckCount,
+ DeltaTime ));
+ }
+ else if (( 1000 * 1000 ) > DeltaTime ) {
+ Value = (UINT32)DeltaTime;
+ DEBUG (( DEBUG_WINDOW,
+ "WindowSize: %d, Threshold: %d, AckCount: %4d, RTT: %d.%03d uSec\r\n",
+ pContext->WindowSize,
+ pContext->Threshold,
+ pContext->AckCount,
+ Value / 1000,
+ Value % 1000 ));
+ }
+ else if (( 1000 * 1000 * 1000 ) > DeltaTime ) {
+ Value = (UINT32)DivU64x32 ( DeltaTime, 1000 );
+ DEBUG (( DEBUG_WINDOW,
+ "WindowSize: %d, Threshold: %d, AckCount: %4d, RTT: %d.%03d mSec\r\n",
+ pContext->WindowSize,
+ pContext->Threshold,
+ pContext->AckCount,
+ Value / 1000,
+ Value % 1000 ));
+ }
+ else {
+ Value = (UINT32)DivU64x32 ( DeltaTime, 1000 * 1000 );
+ DEBUG (( DEBUG_WINDOW,
+ "WindowSize: %d, Threshold: %d, AckCount: %4d, RTT: %d.%03d Sec\r\n",
+ pContext->WindowSize,
+ pContext->Threshold,
+ pContext->AckCount,
+ Value / 1000,
+ Value % 1000 ));
+ }
+ DEBUG_CODE_END ( );
+
+ //
+ // Retransmit the first packet in the window
+ //
+ pPacket = pContext->pTxHead;
+ if ( NULL != pPacket ) {
+ PacketTx ( pContext, pPacket );
+ }
+
+ DBG_EXIT ( );
+ }
+}
+
+
+/**
+ Entry point for the TFTP server application.
+
+ @param [in] Argc The number of arguments
+ @param [in] Argv The argument value array
+
+ @retval 0 The application exited normally.
+ @retval Other An error occurred.
+**/
+int
+main (
+ IN int Argc,
+ IN char **Argv
+ )
+{
+ UINTN Index;
+ TSDT_TFTP_SERVER * pTftpServer;
+ EFI_STATUS Status;
+ UINT64 TriggerTime;
+
+ //
+ // Get the performance counter characteristics
+ //
+ pTftpServer = &mTftpServer;
+ if ( PcdGetBool ( Tftp_HighSpeed )
+ || PcdGetBool ( Tftp_Bandwidth )) {
+ pTftpServer->ClockFrequency = GetPerformanceCounterProperties ( &pTftpServer->Time1,
+ &pTftpServer->Time2 );
+ }
+
+ //
+ // Create a timer event to start TFTP port
+ //
+ Status = gBS->CreateEvent ( EVT_TIMER,
+ TPL_TFTP_SERVER,
+ NULL,
+ NULL,
+ &pTftpServer->TimerEvent );
+ if ( !EFI_ERROR ( Status )) {
+ //
+ // Compute the poll interval
+ //
+ TriggerTime = TFTP_PORT_POLL_DELAY * ( 1000 * 10 );
+ Status = gBS->SetTimer ( pTftpServer->TimerEvent,
+ TimerPeriodic,
+ TriggerTime );
+ if ( !EFI_ERROR ( Status )) {
+ DEBUG (( DEBUG_TFTP_PORT, "TFTP port timer started\r\n" ));
+
+ //
+ // Run the TFTP server forever
+ //
+ pTftpServer->Udpv4Index = -1;
+ pTftpServer->Udpv6Index = -1;
+ do {
+ //
+ // Poll the network layer to create the TFTP port
+ // for the tftp 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.
+ //
+ if ( DIM ( pTftpServer->TftpPort ) != pTftpServer->Entries ) {
+ do {
+ //
+ // Wait a while before polling for a connection
+ //
+ if ( EFI_SUCCESS != gBS->CheckEvent ( pTftpServer->TimerEvent )) {
+ if ( 0 == pTftpServer->Entries ) {
+ break;
+ }
+ gBS->WaitForEvent ( 1, &pTftpServer->TimerEvent, &Index );
+ }
+
+ //
+ // Poll for a network connection
+ //
+ TftpServerSocket ( pTftpServer,
+ AF_INET,
+ &pTftpServer->Udpv4Index );
+ TftpServerSocket ( pTftpServer,
+ AF_INET6,
+ &pTftpServer->Udpv6Index );
+ } while ( 0 == pTftpServer->Entries );
+ }
+
+ //
+ // Poll the socket for activity
+ //
+ do {
+ SocketPoll ( pTftpServer );
+
+ //
+ // Normal TFTP lets the client request the retransmit by
+ // sending another ACK for the previous packet
+ //
+ if ( PcdGetBool ( Tftp_HighSpeed )) {
+ UINT64 CurrentTime;
+ UINT64 ElapsedTime;
+ TSDT_CONNECTION_CONTEXT * pContext;
+ TFTP_PACKET * pPacket;
+
+ //
+ // High speed TFTP uses an agressive retransmit to
+ // get the TFTP client moving again when the ACK or
+ // previous data packet was lost.
+ //
+ // Get the current time
+ //
+ CurrentTime = GetPerformanceCounter ( );
+
+ //
+ // Walk the list of contexts
+ //
+ pContext = pTftpServer->pContextList;
+ while ( NULL != pContext )
+ {
+ //
+ // Check for a transmit timeout
+ //
+ pPacket = pContext->pTxHead;
+ if ( NULL != pPacket ) {
+ //
+ // Compute the elapsed time
+ //
+ if ( pTftpServer->Time2 > pTftpServer->Time1 ) {
+ ElapsedTime = CurrentTime - pPacket->TxTime;
+ }
+ else {
+ ElapsedTime = pPacket->TxTime - CurrentTime;
+ }
+ ElapsedTime = GetTimeInNanoSecond ( ElapsedTime );
+
+ //
+ // Determine if a retransmission is necessary
+ //
+ if ( ElapsedTime >= pContext->Rtt2x ) {
+ DEBUG (( DEBUG_WINDOW,
+ "0x%08x: Context TX timeout for packet 0x%08x, Window: %d\r\n",
+ pContext,
+ pPacket,
+ pContext->WindowSize ));
+ WindowTimeout ( pContext );
+ }
+ }
+
+ //
+ // Set the next context
+ //
+ pContext = pContext->pNext;
+ }
+ }
+ } while ( DIM ( pTftpServer->TftpPort ) == pTftpServer->Entries );
+ } while ( !mbTftpServerExit );
+
+ //
+ // Done with the timer event
+ //
+ gBS->SetTimer ( pTftpServer->TimerEvent,
+ TimerCancel,
+ 0 );
+ }
+ gBS->CloseEvent ( pTftpServer->TimerEvent );
+ }
+
+ //
+ // Return the final status
+ //
+ DBG_EXIT_STATUS ( Status );
+ return Status;
+}
diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/TftpServer/TftpServer.h b/uefi/linaro-edk2/AppPkg/Applications/Sockets/TftpServer/TftpServer.h
new file mode 100644
index 0000000..2166893
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/TftpServer/TftpServer.h
@@ -0,0 +1,431 @@
+/** @file
+ Definitions for the TFTP server.
+
+ Copyright (c) 2011, 2012, Intel Corporation
+ All rights reserved. This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef _TFTP_SERVER_H_
+#define _TFTP_SERVER_H_
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <Uefi.h>
+
+#include <Guid/EventGroup.h>
+
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PcdLib.h>
+#include <Library/TimerLib.h>
+#include <Library/UefiApplicationEntryPoint.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiLib.h>
+#include <Protocol/BlockIo.h>
+
+#include <netinet/in.h>
+#include <netinet6/in6.h>
+
+#include <sys/EfiSysCall.h>
+#include <sys/poll.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+
+//------------------------------------------------------------------------------
+// Macros
+//------------------------------------------------------------------------------
+
+#if defined(_MSC_VER) /* Handle Microsoft VC++ compiler specifics. */
+#define DBG_ENTER() DEBUG (( DEBUG_ENTER_EXIT, "Entering " __FUNCTION__ "\n" )) ///< Display routine entry
+#define DBG_EXIT() DEBUG (( DEBUG_ENTER_EXIT, "Exiting " __FUNCTION__ "\n" )) ///< Display routine exit
+#define DBG_EXIT_DEC(Status) DEBUG (( DEBUG_ENTER_EXIT, "Exiting " __FUNCTION__ ", Status: %d\n", Status )) ///< Display routine exit with decimal value
+#define DBG_EXIT_HEX(Status) DEBUG (( DEBUG_ENTER_EXIT, "Exiting " __FUNCTION__ ", Status: 0x%08x\n", Status )) ///< Display routine exit with hex value
+#define DBG_EXIT_STATUS(Status) DEBUG (( DEBUG_ENTER_EXIT, "Exiting " __FUNCTION__ ", Status: %r\n", Status )) ///< Display routine exit with status value
+#define DBG_EXIT_TF(Status) DEBUG (( DEBUG_ENTER_EXIT, "Exiting " __FUNCTION__ ", returning %s\n", (FALSE == Status) ? L"FALSE" : L"TRUE" )) ///< Display routine with TRUE/FALSE value
+#else // _MSC_VER
+#define DBG_ENTER()
+#define DBG_EXIT()
+#define DBG_EXIT_DEC(Status)
+#define DBG_EXIT_HEX(Status)
+#define DBG_EXIT_STATUS(Status)
+#define DBG_EXIT_TF(Status)
+#endif // _MSC_VER
+
+#define DIM(x) ( sizeof ( x ) / sizeof ( x[0] )) ///< Compute the number of entries in an array
+
+//------------------------------------------------------------------------------
+// Constants
+//------------------------------------------------------------------------------
+
+#define ACK_SHIFT 4 ///< Number of samples in ACK average
+
+#define DEBUG_WINDOW 0x00000001 ///< Display the window messages
+#define DEBUG_TX_PACKET 0x00000002 ///< Display the transmit packet messages
+#define DEBUG_FILE_BUFFER 0x00000004 ///< Display the file buffer messages
+#define DEBUG_SERVER_TIMER 0x00000008 ///< Display the socket poll messages
+#define DEBUG_TFTP_REQUEST 0x00000010 ///< Display the TFTP request messages
+#define DEBUG_PORT_WORK 0x00000020 ///< Display the port work messages
+#define DEBUG_SOCKET_POLL 0x00000040 ///< Display the socket poll messages
+#define DEBUG_TFTP_PORT 0x00000080 ///< Display the TFTP port messages
+#define DEBUG_TX 0x00000100 ///< Display transmit messages
+#define DEBUG_RX 0x00000200 ///< Display receive messages
+#define DEBUG_TFTP_ACK 0x00000400 ///< Display the TFTP ACK messages
+#define DEBUG_ENTER_EXIT 0x00000800 ///< Display entry and exit messages
+
+#define MAX_PACKETS 8 ///< Maximum number of packets in the window
+
+#define TFTP_PORT_POLL_DELAY ( 2 * 1000 ) ///< Delay in milliseconds for attempts to open the TFTP port
+#define CLIENT_POLL_DELAY 50 ///< Delay in milliseconds between client polls
+
+#define TPL_TFTP_SERVER TPL_CALLBACK ///< TPL for routine synchronization
+
+/**
+ Verify new TPL value
+
+ This macro which is enabled when debug is enabled verifies that
+ the new TPL value is >= the current TPL value.
+**/
+#ifdef VERIFY_TPL
+#undef VERIFY_TPL
+#endif // VERIFY_TPL
+
+#if !defined(MDEPKG_NDEBUG)
+
+#define VERIFY_TPL(tpl) \
+{ \
+ EFI_TPL PreviousTpl; \
+ \
+ PreviousTpl = gBS->RaiseTPL ( TPL_HIGH_LEVEL ); \
+ gBS->RestoreTPL ( PreviousTpl ); \
+ if ( PreviousTpl > tpl ) { \
+ DEBUG (( DEBUG_ERROR, "Current TPL: %d, New TPL: %d\r\n", PreviousTpl, tpl )); \
+ ASSERT ( PreviousTpl <= tpl ); \
+ } \
+}
+
+#else // MDEPKG_NDEBUG
+
+#define VERIFY_TPL(tpl)
+
+#endif // MDEPKG_NDEBUG
+
+#define TFTP_SERVER_SIGNATURE SIGNATURE_32('T','F','T','P') ///< TSDT_TFTP_SERVER memory signature
+
+//
+// See: http://www.rfc-editor.org/rfc/pdfrfc/rfc1350.txt.pdf
+//
+// TFTP Operations
+//
+
+#define TFTP_OP_READ_REQUEST 1 ///< Read request, zero terminated file name, zero terminated mode
+#define TFTP_OP_WRITE_REQUEST 2 ///< Write request, zero terminated file name, zero terminated mode
+#define TFTP_OP_DATA 3 ///< Data block, end-of-file indicated by short block
+#define TFTP_OP_ACK 4 ///< ACK block number
+#define TFTP_OP_ERROR 5 ///< Error number and explaination
+#define TFTP_OP_OACK 6 ///< ACK the options
+
+#define TFTP_MAX_BLOCK_SIZE 4096 ///< Maximum block size
+
+#define TFTP_ERROR_SEE_MSG 0 ///< See the error message
+#define TFTP_ERROR_NOT_FOUND 1 ///< File not found
+#define TFTP_ERROR_ACCESS_VIOLATION 2 ///< Access violation
+#define TFTP_ERROR_DISK_FULL 3 ///< Disk full
+#define TFTP_ERROR_ILLEGAL_OP 4 ///< Illegal operation
+#define TFTP_ERROR_UNKNOWN_XFER_ID 5 ///< Unknown transfer ID
+#define TFTP_ERROR_FILE_EXISTS 6 ///< File already exists
+#define TFTP_ERROR_NO_SUCH_USER 7 ///< No such user
+
+//------------------------------------------------------------------------------
+// Data Types
+//------------------------------------------------------------------------------
+
+/**
+ Packet structure
+**/
+typedef struct _TFTP_PACKET TFTP_PACKET;
+typedef struct _TFTP_PACKET {
+ TFTP_PACKET * pNext; ///< Next packet in list
+ UINT64 TxTime; ///< Time the transmit was performed
+ ssize_t TxBytes; ///< Bytes in the TX buffer
+ UINT32 RetryCount; ///< Number of transmissions
+ UINT16 BlockNumber; ///< Block number of this packet
+ UINT8 TxBuffer[ 2 + 2 + TFTP_MAX_BLOCK_SIZE ]; ///< Transmit buffer
+} GCC_TFTP_PACKET;
+
+/**
+ Port control structure
+**/
+typedef struct _TSDT_CONNECTION_CONTEXT TSDT_CONNECTION_CONTEXT;
+typedef struct _TSDT_CONNECTION_CONTEXT {
+ //
+ // Remote connection management
+ //
+ TSDT_CONNECTION_CONTEXT * pNext; ///< Next context in the connection list
+ struct sockaddr_in6 RemoteAddress; ///< Remote address
+ int SocketFd; ///< Socket file descriptor
+
+ //
+ // File management parameters
+ //
+ FILE * File; ///< NULL while file is closed
+ UINT64 LengthInBytes; ///< Size of the file
+ UINT64 BytesRemaining; ///< Number of bytes remaining to be sent
+ UINT64 BytesToSend; ///< Number of bytes to send
+ UINT64 ValidBytes; ///< Number of valid bytes in the buffer
+ BOOLEAN bEofSent; ///< End of file sent
+ UINT8 * pFill; ///< Next portion of the buffer to fill
+ UINT8 * pBuffer; ///< Pointer into the file data
+ UINT8 * pEnd; ///< End of the file data
+ UINT8 FileData[ 2 * MAX_PACKETS * TFTP_MAX_BLOCK_SIZE ]; ///< File data to send
+ UINT64 TimeStart; ///< Start of file transfer
+
+ //
+ // TFTP management parameters
+ //
+ UINT16 BlockNumber; ///< Next block to be transmitted
+ UINT32 BlockSize; ///< Negotiated block size
+
+ //
+ // Window management
+ //
+ UINT32 AckCount; ///< Number of ACKs to receive before increasing the window
+ UINT32 PacketsInWindow; ///< Number of packets in the window
+ UINT32 Threshold; ///< Size of window when ACK count becomes logrithmic
+ UINT32 WindowSize; ///< Size of the transmit window
+ UINT64 MaxTimeout; ///< Maximum number of seconds to wait before retransmission
+ UINT64 Rtt2x; ///< Twice the average round trip time in nanoseconds
+
+ //
+ // Buffer management
+ //
+ TFTP_PACKET * pFreeList; ///< List of free packets
+ TFTP_PACKET * pTxHead; ///< First packet in the list of packets for transmission
+ TFTP_PACKET * pTxTail; ///< Last packet in the list of packets for transmission
+ TFTP_PACKET ErrorPacket; ///< Error packet
+ TFTP_PACKET Tx[ MAX_PACKETS ];///< Transmit packets
+}GCC_TSDT_CONNECTION_CONTEXT;
+
+/**
+ TFTP server control structure
+**/
+typedef struct {
+ UINTN Signature; ///< Structure identification
+
+ //
+ // Image attributes
+ //
+ EFI_HANDLE ImageHandle; ///< Image handle
+
+ //
+ // Performance management
+ //
+ UINT64 ClockFrequency; ///< Frequency of the clock
+ UINT64 Time1; ///< Clock value after rollover
+ UINT64 Time2; ///< Clock value before rollover
+ UINT64 RxTime; ///< Time when the packet was recevied
+
+ //
+ // TFTP port management
+ //
+ EFI_EVENT TimerEvent; ///< Timer to open TFTP port
+ int Udpv4Index; ///< Entry for UDPv4
+ int Udpv6Index; ///< Entry for UDPv6
+ int Entries; ///< Number of TFTP ports
+ struct pollfd TftpPort [ 2 ]; ///< Poll descriptor for the TFTP ports (UDP4, UDP6)
+
+ //
+ // Request management
+ //
+ union {
+ struct sockaddr_in v4; ///< UDP4 address
+ struct sockaddr_in6 v6; ///< UDP6 address
+ } RemoteAddress; ///< Remote address
+ ssize_t RxBytes; ///< Receive data length in bytes
+ UINT8 RxBuffer[ 2 + 2 + TFTP_MAX_BLOCK_SIZE ]; ///< Receive buffer
+
+ //
+ // Client port management
+ //
+ TSDT_CONNECTION_CONTEXT * pContextList; ///< List of connection context structures
+} TSDT_TFTP_SERVER;
+
+//#define SERVER_FROM_SERVICE(a) CR(a, TSDT_TFTP_SERVER, ServiceBinding, TFTP_SERVER_SIGNATURE) ///< Locate DT_LAYER from service binding
+
+extern TSDT_TFTP_SERVER mTftpServer;
+
+//------------------------------------------------------------------------------
+// Support routines
+//------------------------------------------------------------------------------
+
+/**
+ Queue data packets for transmission
+
+ @param [in] pContext Connection context structure address
+
+ @retval TRUE if a read error occurred
+
+**/
+BOOLEAN
+PacketFill (
+ IN TSDT_CONNECTION_CONTEXT * pContext
+ );
+
+/**
+ Free the packet
+
+ @param [in] pContext Address of a ::TSDT_CONNECTION_CONTEXT structure
+ @param [in] pPacket Address of a ::TFTP_PACKET structure
+
+**/
+VOID
+PacketFree(
+ IN TSDT_CONNECTION_CONTEXT * pContext,
+ IN TFTP_PACKET * pPacket
+ );
+
+/**
+ Get a packet for transmission
+
+ @param [in] pContext Address of a ::TSDT_CONNECTION_CONTEXT structure
+
+ @retval Address of a ::TFTP_PACKET structure
+
+**/
+TFTP_PACKET *
+PacketGet (
+ IN TSDT_CONNECTION_CONTEXT * pContext
+ );
+
+/**
+ Queue the packet for transmission
+
+ @param [in] pContext Address of a ::TSDT_CONNECTION_CONTEXT structure
+ @param [in] pPacket Address of a ::TFTP_PACKET structure
+
+ @retval TRUE if a transmission error has occurred
+
+**/
+BOOLEAN
+PacketQueue (
+ IN TSDT_CONNECTION_CONTEXT * pContext,
+ IN TFTP_PACKET * pPacket
+ );
+
+/**
+ Transmit the packet
+
+ @param [in] pContext Address of a ::TSDT_CONNECTION_CONTEXT structure
+ @param [in] pPacket Address of a ::TFTP_PACKET structure
+
+ @retval EFI_SUCCESS Message processed successfully
+
+**/
+EFI_STATUS
+PacketTx (
+ IN TSDT_CONNECTION_CONTEXT * pContext,
+ IN TFTP_PACKET * pPacket
+ );
+
+/**
+ Build and send an error packet
+
+ @param [in] pContext The context structure address.
+ @param [in] Error Error number for the packet
+ @param [in] pError Zero terminated error string address
+
+ @retval EFI_SUCCESS Message processed successfully
+
+**/
+EFI_STATUS
+SendError (
+ IN TSDT_CONNECTION_CONTEXT * pContext,
+ IN UINT16 Error,
+ IN UINT8 * pError
+ );
+
+/**
+ Process the TFTP request
+
+ @param [in] pOption Address of the first zero terminated option string
+ @param [in] pValue Address to receive the value
+
+ @retval EFI_SUCCESS Option translated into a value
+
+**/
+EFI_STATUS
+TftpOptionValue (
+ IN UINT8 * pOption,
+ IN INT32 * pValue
+ );
+
+/**
+ Process the TFTP request
+
+ @param [in] pTftpServer The TFTP server control structure address.
+ @param [in] pContext Connection context structure address
+ @param [in] SocketFd Socket file descriptor
+
+**/
+VOID
+TftpProcessRequest (
+ IN TSDT_TFTP_SERVER * pTftpServer,
+ IN TSDT_CONNECTION_CONTEXT * pContext,
+ IN int SocketFd
+ );
+
+/**
+ Process the read request
+
+ @param [in] pTftpServer Address of the ::TSDT_TFTP_SERVER structure
+ @param [in] pContext Connection context structure address
+ @param [in] SocketFd Socket file descriptor
+
+ @retval TRUE if the context should be closed
+
+**/
+BOOLEAN
+TftpRead (
+ IN TSDT_TFTP_SERVER * pTftpServer,
+ IN TSDT_CONNECTION_CONTEXT * pContext,
+ IN int SocketFd
+ );
+
+/**
+ Update the window due to the ACK
+
+ @param [in] pTftpServer Address of the ::TSDT_TFTP_SERVER structure
+ @param [in] pContext Address of a ::TSDT_CONNECTION_CONTEXT structure
+ @param [in] pPacket Address of a ::TFTP_PACKET structure
+
+**/
+VOID
+WindowAck (
+ IN TSDT_TFTP_SERVER * pTftpServer,
+ IN TSDT_CONNECTION_CONTEXT * pContext,
+ IN TFTP_PACKET * pPacket
+ );
+
+/**
+ A timeout has occurred, close the window
+
+ @param [in] pContext Address of a ::TSDT_CONNECTION_CONTEXT structure
+
+**/
+VOID
+WindowTimeout (
+ IN TSDT_CONNECTION_CONTEXT * pContext
+ );
+
+//------------------------------------------------------------------------------
+
+#endif // _TFTP_SERVER_H_
diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/TftpServer/TftpServer.inf b/uefi/linaro-edk2/AppPkg/Applications/Sockets/TftpServer/TftpServer.inf
new file mode 100644
index 0000000..79513c2
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/TftpServer/TftpServer.inf
@@ -0,0 +1,70 @@
+## @file
+# TFTP Server Application
+#
+# Copyright (c) 2011-2012, Intel Corporation
+# All rights reserved. This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = TftpServer
+ FILE_GUID = 94621F9E-B5CA-4cfd-82BE-0C542EB0D9BE
+ MODULE_TYPE = UEFI_APPLICATION
+ VERSION_STRING = 1.0
+ ENTRY_POINT = ShellCEntryLib
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF EBC
+#
+
+[Sources]
+ TftpServer.h
+ TftpServer.c
+
+
+[Pcd]
+ gAppPkgTokenSpaceGuid.Tftp_AckLogBase
+ gAppPkgTokenSpaceGuid.Tftp_AckMultiplier
+ gAppPkgTokenSpaceGuid.Tftp_Bandwidth
+ gAppPkgTokenSpaceGuid.Tftp_HighSpeed
+ gAppPkgTokenSpaceGuid.Tftp_MaxRetry
+ gAppPkgTokenSpaceGuid.Tftp_MaxTimeoutInSec
+
+
+[Packages]
+ AppPkg/AppPkg.dec
+ MdePkg/MdePkg.dec
+ ShellPkg/ShellPkg.dec
+ StdLib/StdLib.dec
+
+
+[LibraryClasses]
+ BaseMemoryLib
+ BsdSocketLib
+ DebugLib
+ DevMedia
+ EfiSocketLib
+ LibC
+ ShellLib
+ ShellCEntryLib
+ TimerLib
+ UefiBootServicesTableLib
+ UefiLib
+ UefiRuntimeServicesTableLib
+# UseSocketDxe
+
+[BuildOptions]
+ INTEL:*_*_*_CC_FLAGS = /Qdiag-disable:181,186
+ MSFT:*_*_*_CC_FLAGS = /Od
+ GCC:*_*_*_CC_FLAGS = -O0 -Wno-unused-variable
+
diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/WebServer/ACPI.c b/uefi/linaro-edk2/AppPkg/Applications/Sockets/WebServer/ACPI.c
new file mode 100644
index 0000000..e086a2d
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/WebServer/ACPI.c
@@ -0,0 +1,2557 @@
+/**
+ @file
+ Display the ACPI tables
+
+ Copyright (c) 2011-2012, Intel Corporation
+ All rights reserved. This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <WebServer.h>
+#include <Guid/Acpi.h>
+#include <IndustryStandard/Acpi10.h>
+#include <IndustryStandard/Acpi30.h>
+
+#if defined(_MSC_VER) // Handle Microsoft VC++ compiler specifics.
+#pragma warning ( disable : 4305 )
+#endif // defined(_MSC_VER)
+
+//
+// Ensure proper structure formats
+//
+#pragma pack(1)
+
+typedef struct {
+ UINT8 AddressSpaceId;
+ UINT8 RegisterBitWidth;
+ UINT8 RegisterBitOffset;
+ UINT8 AccessSize;
+ UINT64 Address;
+} GENERIC_ADDRESS;
+
+
+typedef struct {
+ UINT32 Signature; // 0
+ UINT32 Length; // 4
+ UINT8 Revision; // 8
+ UINT8 Checksum; // 9
+ UINT8 OemId[6]; // 10
+ UINT8 OemTableId[8]; // 16
+ UINT32 OemRevision; // 24
+ UINT32 CreatorId; // 28
+ UINT32 CreatorRevision; // 32
+ UINT8 DefinitionBlock[1]; // 36
+} ACPI_DSDT;
+
+
+typedef struct {
+ UINT32 Signature; // 0
+ UINT32 Length; // 4
+ UINT8 Revision; // 8
+ UINT8 Checksum; // 9
+ UINT8 OemId[6]; // 10
+ UINT8 OemTableId[8]; // 16
+ UINT32 OemRevision; // 24
+ UINT32 CreatorId; // 28
+ UINT32 CreatorRevision; // 32
+ UINT32 FirmwareCtrl; // 36
+ UINT32 DSDT; // 40
+ UINT8 Reserved; // 44
+ UINT8 PreferredPmProfile; // 45
+ UINT16 SciInt; // 46
+ UINT32 SmiCmd; // 48
+ UINT8 AcpiEnable; // 52
+ UINT8 AcpiDisable; // 53
+ UINT8 S4BiosReq; // 54
+ UINT8 PStateCnt; // 55
+ UINT32 Pm1aEvtBlk; // 56
+ UINT32 Pm1bEvtBlk; // 60
+ UINT32 Pm1aCntBlk; // 64
+ UINT32 Pm1bCntBlk; // 68
+ UINT32 Pm2CntBlk; // 72
+ UINT32 PmTmrBlk; // 76
+ UINT32 Gpe0Blk; // 80
+ UINT32 Gpe1Blk; // 84
+ UINT8 Pm1EvtLen; // 88
+ UINT8 Pm1CntLen; // 89
+ UINT8 PM2CntLen; // 90
+ UINT8 PmTmrLen; // 91
+ UINT8 Gpe0BlkLen; // 92
+ UINT8 Gpe1BlkLen; // 93
+ UINT8 Gpe1Base; // 94
+ UINT8 CstCnt; // 95
+ UINT16 PLvl2Lat; // 96
+ UINT16 PLvl3Lat; // 98
+ UINT16 FlushSize; // 100
+ UINT16 FlushStride; // 102
+ UINT8 DutyOffset; // 104
+ UINT8 DutyWidth; // 105
+ UINT8 DayAlrm; // 106
+ UINT8 MonAlrm; // 107
+ UINT8 Century; // 108
+ UINT16 IapcBootArch; // 109
+ UINT8 Reserved2; // 111
+ UINT32 Flags; // 112
+ UINT32 ResetReg[3]; // 116
+ UINT8 ResetValue; // 128
+ UINT8 Reserved3[3]; // 129
+ UINT64 XFirmwareCtrl; // 132
+ UINT64 XDsdt; // 140
+ UINT32 XPm1aEvtBlk[3]; // 148
+ UINT32 XPm1bEvtBlk[3]; // 160
+ UINT32 XPm1aCntBlk[3]; // 172
+ UINT32 XPm1bCntBlk[3]; // 184
+ UINT32 XPm2CntBlk[3]; // 196
+ UINT32 XPmTmrBlk[3]; // 208
+ UINT32 XGpe0Blk[3]; // 220
+ UINT32 XGpe1Blk[3]; // 232
+} ACPI_FADT;
+
+
+typedef struct {
+ UINT32 Signature;
+ UINT32 Length;
+ UINT8 Revision;
+ UINT8 Checksum;
+ UINT8 OemId[6];
+ UINT8 OemTableId[8];
+ UINT32 OemRevision;
+ UINT32 CreatorId;
+ UINT32 CreatorRevision;
+ UINT32 Entry[1];
+} ACPI_RSDT;
+
+
+typedef struct {
+ UINT32 Signature; // 0
+ UINT32 Length; // 4
+} ACPI_UNKNOWN;
+
+#pragma pack()
+
+
+typedef struct {
+ UINT32 Signature;
+ CONST CHAR8 * pTableName;
+ CONST CHAR16 * pWebPage;
+} TABLE_SIGNATURE;
+
+
+CONST TABLE_SIGNATURE mTableId[] = {
+ { APIC_SIGNATURE, "APIC", PAGE_ACPI_APIC },
+ { BGRT_SIGNATURE, "BGRT", PAGE_ACPI_BGRT },
+ { DSDT_SIGNATURE, "DSDT", PAGE_ACPI_DSDT },
+ { FADT_SIGNATURE, "FADT", PAGE_ACPI_FADT },
+ { HPET_SIGNATURE, "HPET", PAGE_ACPI_HPET },
+ { MCFG_SIGNATURE, "MCFG", PAGE_ACPI_MCFG },
+ { SSDT_SIGNATURE, "SSDT", PAGE_ACPI_SSDT },
+ { TCPA_SIGNATURE, "TCPA", PAGE_ACPI_TCPA },
+ { UEFI_SIGNATURE, "UEFI", PAGE_ACPI_UEFI }
+};
+
+
+/**
+ Locate the RSDT table
+
+ @return Table address or NULL if not found
+
+**/
+CONST ACPI_RSDT *
+LocateRsdt (
+ VOID
+ )
+{
+ CONST EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER * pRsdp10b;
+ CONST EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER * pRsdp30;
+ CONST ACPI_RSDT * pRsdt;
+ EFI_STATUS Status;
+
+ //
+ // Use for/break instead of goto
+ //
+ pRsdt = NULL;
+ for ( ; ; ) {
+ //
+ // Locate the RSDT
+ //
+ Status = EfiGetSystemConfigurationTable ( &gEfiAcpiTableGuid, (VOID **)&pRsdp30 );
+ if ( !EFI_ERROR ( Status )) {
+ pRsdt = (ACPI_RSDT *)(UINTN)pRsdp30->RsdtAddress;
+ }
+ else {
+ Status = EfiGetSystemConfigurationTable (&gEfiAcpi10TableGuid, (VOID **)&pRsdp10b );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ pRsdt = (ACPI_RSDT *)(UINTN)pRsdp10b->RsdtAddress;
+ }
+ break;
+ }
+
+ //
+ // The entry was not found
+ //
+ return pRsdt;
+}
+
+
+/**
+ Locate the specified table
+
+ @param [in] Signature Table signature
+
+ @return Table address or NULL if not found
+
+**/
+CONST VOID *
+LocateTable (
+ IN UINT32 Signature
+ )
+{
+ CONST UINT32 * pEnd;
+ CONST UINT32 * pEntry;
+ CONST EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER * pRsdp10b;
+ CONST EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER * pRsdp30;
+ CONST ACPI_RSDT * pRsdt;
+ CONST UINT32 * pSignature;
+ EFI_STATUS Status;
+
+ //
+ // Use for/break instead of goto
+ //
+ for ( ; ; ) {
+ //
+ // Locate the RSDT
+ //
+ Status = EfiGetSystemConfigurationTable ( &gEfiAcpiTableGuid, (VOID **)&pRsdp30 );
+ if ( !EFI_ERROR ( Status )) {
+ pRsdt = (ACPI_RSDT *)(UINTN)pRsdp30->RsdtAddress;
+ }
+ else {
+ Status = EfiGetSystemConfigurationTable (&gEfiAcpi10TableGuid, (VOID **)&pRsdp10b );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ pRsdt = (ACPI_RSDT *)(UINTN)pRsdp10b->RsdtAddress;
+ }
+
+ //
+ // Walk the list of entries
+ //
+ pEntry = &pRsdt->Entry[ 0 ];
+ pEnd = &pEntry[(( pRsdt->Length - sizeof ( *pRsdt )) >> 2 ) + 1 ];
+ while ( pEnd > pEntry ) {
+ //
+ // The entry is actually a 32-bit physical table address
+ // The first entry in the table is the 32-bit table signature
+ //
+ pSignature = (UINT32 *)(UINTN)*pEntry;
+ if ( *pSignature == Signature ) {
+ return (CONST VOID *)(UINTN)*pEntry;
+ }
+
+ //
+ // Set the next entry
+ //
+ pEntry++;
+ }
+ break;
+ }
+
+ //
+ // The entry was not found
+ //
+ return NULL;
+}
+
+
+/**
+ Display a row containing a hex value
+
+ @param [in] SocketFD The socket's file descriptor to add to the list.
+ @param [in] pPort The WSDT_PORT structure address
+ @param [in] pName Address of a zero terminated name string
+ @param [in] Length Length in bytes
+ @param [in] pChar Address of the first character
+
+ @retval EFI_SUCCESS The request was successfully processed
+
+**/
+EFI_STATUS
+RowAnsiArray (
+ IN int SocketFD,
+ IN WSDT_PORT * pPort,
+ IN CONST CHAR8 * pName,
+ IN UINTN Length,
+ IN CONST CHAR8 * pChar
+ )
+{
+ CONST CHAR8 * pData;
+ CONST CHAR8 * pEnd;
+ EFI_STATUS Status;
+
+ DBG_ENTER ( );
+
+ //
+ // Use for/break instead of goto
+ //
+ for ( ; ; ) {
+ //
+ // Start the row
+ //
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ "<tr><td>" );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ pName );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ "</td><td><code>" );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Display the characters
+ //
+ pData = pChar;
+ pEnd = &pChar[ Length ];
+ while ( pEnd > pData ) {
+ Status = HttpSendCharacter ( SocketFD,
+ pPort,
+ *pData++,
+ " " );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ }
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Display the byte values
+ //
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ "<br/>0x" );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ pData = pChar;
+ while ( pEnd > pData ) {
+ Status = HttpSendHexBits ( SocketFD,
+ pPort,
+ 8,
+ *pData++ );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ if ( pEnd > pData ) {
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ " 0x" );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ }
+ }
+
+ //
+ // Terminate the row
+ //
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ "</code></td></tr>\r\n" );
+ break;
+ }
+
+ //
+ // Return the operation status
+ //
+ DBG_EXIT_STATUS ( Status );
+ return Status;
+}
+
+
+/**
+ Format a row with a list of bytes
+
+ @param [in] SocketFD The socket's file descriptor to add to the list.
+ @param [in] pPort The WSDT_PORT structure address
+ @param [in] pName Zero terminated name string
+ @param [in] ByteCount The number of bytes to display
+ @param [in] pData Address of the byte array
+
+ @retval EFI_SUCCESS The request was successfully processed
+
+**/
+EFI_STATUS
+RowBytes (
+ IN int SocketFD,
+ IN WSDT_PORT * pPort,
+ IN CHAR8 * pName,
+ IN UINTN ByteCount,
+ IN CONST UINT8 * pData
+ )
+{
+ CONST UINT8 * pEnd;
+ EFI_STATUS Status;
+
+ //
+ // Use for/break instead of goto
+ //
+ for ( ; ; ) {
+ //
+ // Start the row
+ //
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ "<tr><td>" );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Display the field name
+ //
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ pName );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Display the field value
+ //
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ "</td><td><code>0x" );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ pEnd = &pData[ ByteCount ];
+ while ( pEnd > pData ) {
+ Status = HttpSendHexBits ( SocketFD,
+ pPort,
+ 8,
+ *pData++ );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ if ( pEnd > pData ) {
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ " 0x" );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ }
+ }
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Terminate the row
+ //
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ "</code></td></tr>\r\n" );
+ break;
+ }
+
+ //
+ // Return the operation status
+ //
+ return Status;
+}
+
+
+/**
+ Format a row with a list of bytes
+
+ @param [in] SocketFD The socket's file descriptor to add to the list.
+ @param [in] pPort The WSDT_PORT structure address
+ @param [in] pName Zero terminated name string
+ @param [in] ByteCount The number of bytes to display
+ @param [in] pData Address of the byte array
+
+ @retval EFI_SUCCESS The request was successfully processed
+
+**/
+EFI_STATUS
+RowDump (
+ IN int SocketFD,
+ IN WSDT_PORT * pPort,
+ IN CHAR8 * pName,
+ IN UINTN ByteCount,
+ IN CONST UINT8 * pData
+ )
+{
+ EFI_STATUS Status;
+
+ //
+ // Use for/break instead of goto
+ //
+ for ( ; ; ) {
+ //
+ // Start the row
+ //
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ "<tr><td>" );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Display the field name
+ //
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ pName );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Start the field value
+ //
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ "</td><td>" );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Dump the buffer
+ //
+ Status = HttpSendDump ( SocketFD,
+ pPort,
+ ByteCount,
+ pData );
+
+ //
+ // Terminate the field value and row
+ //
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ "</td></tr>\r\n" );
+ break;
+ }
+
+ //
+ // Return the operation status
+ //
+ return Status;
+}
+
+
+/**
+ Format a row with a general address
+
+ @param [in] SocketFD The socket's file descriptor to add to the list.
+ @param [in] pPort The WSDT_PORT structure address
+ @param [in] pName Zero terminated name string
+ @param [in] pAddr Address of the general address buffer
+ @param [in] pWebPage Zero terminated web page address
+
+ @retval EFI_SUCCESS The request was successfully processed
+
+**/
+EFI_STATUS
+RowGenericAddress (
+ IN int SocketFD,
+ IN WSDT_PORT * pPort,
+ IN CHAR8 * pName,
+ IN CONST UINT32 * pAddr,
+ IN CONST CHAR16 * pWebPage
+ )
+{
+ CONST GENERIC_ADDRESS * pGenericAddress;
+ EFI_STATUS Status;
+
+ //
+ // Use for/break instead of goto
+ //
+ for ( ; ; ) {
+ //
+ // Start the row
+ //
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ "<tr><td>" );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Display the field name
+ //
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ pName );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Display the field value
+ //
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ "</td><td><code>" );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Determine the type of address
+ //
+ pGenericAddress = (CONST GENERIC_ADDRESS *)pAddr;
+ if ( 0 == pGenericAddress->AddressSpaceId ) {
+ Status = HttpSendAnsiString ( SocketFD, pPort, "System Memory" );
+ }
+ else if ( 1 == pGenericAddress->AddressSpaceId ) {
+ Status = HttpSendAnsiString ( SocketFD, pPort, "I/O Space" );
+ }
+ else if ( 2 == pGenericAddress->AddressSpaceId ) {
+ Status = HttpSendAnsiString ( SocketFD, pPort, "PCI Configuration Space" );
+ }
+ else if ( 3 == pGenericAddress->AddressSpaceId ) {
+ Status = HttpSendAnsiString ( SocketFD, pPort, "Embedded Controller" );
+ }
+ else if ( 4 == pGenericAddress->AddressSpaceId ) {
+ Status = HttpSendAnsiString ( SocketFD, pPort, "SMBus" );
+ }
+ else if ( 0x7f == pGenericAddress->AddressSpaceId ) {
+ Status = HttpSendAnsiString ( SocketFD, pPort, "Functional Fixed Hardware" );
+ }
+ else if (( 0xc0 <= pGenericAddress->AddressSpaceId )
+ && ( 0xff >= pGenericAddress->AddressSpaceId )) {
+ Status = HttpSendAnsiString ( SocketFD, pPort, "OEM Defined" );
+ }
+ else {
+ Status = HttpSendAnsiString ( SocketFD, pPort, "Reserved" );
+ }
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ "<br/>Register Bit Width: " );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = HttpSendValue ( SocketFD,
+ pPort,
+ pGenericAddress->RegisterBitWidth );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ "<br/>Register Bit Offset: " );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = HttpSendHexValue ( SocketFD,
+ pPort,
+ pGenericAddress->RegisterBitOffset );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ "<br/>Access Size: " );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = HttpSendValue ( SocketFD,
+ pPort,
+ pGenericAddress->AccessSize );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ "<br/>Address: " );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Add the web-page link if necessary
+ //
+ if ( NULL != pWebPage ) {
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ "<a target=\"_blank\" href=\"" );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = HttpSendUnicodeString ( SocketFD,
+ pPort,
+ pWebPage );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ "\">" );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ }
+
+ //
+ // Display the address
+ //
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ "0x" );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = HttpSendHexBits ( SocketFD,
+ pPort,
+ 64,
+ pGenericAddress->Address );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Finish the web-page link if necessary
+ //
+ if ( NULL != pWebPage ) {
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ "</a>" );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ }
+
+ //
+ // Terminate the row
+ //
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ "</code></td></tr>\r\n" );
+ break;
+ }
+
+ //
+ // Return the operation status
+ //
+ return Status;
+}
+
+
+/**
+ Translate a table address into a web page
+
+ @param [in] pSignature Address of the table signature
+ @param [out] ppTableName Address to receive the table name address
+
+ @return Zero terminated web page address or NULL if not found
+
+**/
+CONST CHAR16 *
+SignatureLookup (
+ IN UINT32 * pSignature,
+ OUT CONST CHAR8 ** ppTableName
+ )
+{
+ CONST TABLE_SIGNATURE * pTableId;
+ CONST TABLE_SIGNATURE * pEnd;
+ UINT32 Signature;
+
+ //
+ // Walk the list of tables
+ //
+ Signature = *pSignature;
+ pTableId = &mTableId[ 0 ];
+ pEnd = &pTableId[ sizeof ( mTableId ) / sizeof ( mTableId[ 0 ])];
+ while ( pEnd > pTableId ) {
+ //
+ // Attempt to locate the table signature
+ //
+ if ( pTableId->Signature == Signature ) {
+ //
+ // The signature was found
+ // Return the web page
+ //
+ *ppTableName = pTableId->pTableName;
+ return pTableId->pWebPage;
+ }
+
+ //
+ // Set the next table
+ //
+ pTableId += 1;
+ }
+
+ //
+ // The table was not found
+ //
+ *ppTableName = (CONST CHAR8 *)pSignature;
+ return NULL;
+}
+
+
+/**
+ Respond with the APIC table
+
+ @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
+AcpiApicPage (
+ IN int SocketFD,
+ IN WSDT_PORT * pPort,
+ OUT BOOLEAN * pbDone
+ )
+{
+ CONST ACPI_UNKNOWN * pApic;
+ EFI_STATUS Status;
+
+ DBG_ENTER ( );
+
+ //
+ // Send the APIC page
+ //
+ for ( ; ; ) {
+ //
+ // Locate the APIC
+ //
+ pApic = (ACPI_UNKNOWN *)LocateTable ( APIC_SIGNATURE );
+ if ( NULL == pApic ) {
+ Status = EFI_NOT_FOUND;
+ break;
+ }
+
+ //
+ // Send the page and table header
+ //
+ Status = TableHeader ( SocketFD, pPort, L"APIC Table", pApic );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Display the header
+ //
+ Status = RowAnsiArray ( SocketFD,
+ pPort,
+ "Signature",
+ sizeof ( pApic->Signature ),
+ (CHAR8 *)&pApic->Signature );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowDecimalValue ( SocketFD,
+ pPort,
+ "Length",
+ pApic->Length );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Display the data from the table
+ //
+ Status = RowDump ( SocketFD,
+ pPort,
+ "Data",
+ pApic->Length - sizeof ( *pApic ) + 1,
+ (UINT8 *)( pApic + 1 ));
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Build the table trailer
+ //
+ Status = TableTrailer ( SocketFD,
+ pPort,
+ pbDone );
+ break;
+ }
+
+ //
+ // Return the operation status
+ //
+ DBG_EXIT_STATUS ( Status );
+ return Status;
+}
+
+
+/**
+ Respond with the BGRT table
+
+ @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
+AcpiBgrtPage (
+ IN int SocketFD,
+ IN WSDT_PORT * pPort,
+ OUT BOOLEAN * pbDone
+ )
+{
+ CONST ACPI_UNKNOWN * pBgrt;
+ EFI_STATUS Status;
+
+ DBG_ENTER ( );
+
+ //
+ // Send the BGRT page
+ //
+ for ( ; ; ) {
+ //
+ // Locate the BGRT
+ //
+ pBgrt = (ACPI_UNKNOWN *)LocateTable ( BGRT_SIGNATURE );
+ if ( NULL == pBgrt ) {
+ Status = EFI_NOT_FOUND;
+ break;
+ }
+
+ //
+ // Send the page and table header
+ //
+ Status = TableHeader ( SocketFD, pPort, L"BGRT Table", pBgrt );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Display the header
+ //
+ Status = RowAnsiArray ( SocketFD,
+ pPort,
+ "Signature",
+ sizeof ( pBgrt->Signature ),
+ (CHAR8 *)&pBgrt->Signature );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowDecimalValue ( SocketFD,
+ pPort,
+ "Length",
+ pBgrt->Length );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Display the data from the table
+ //
+ Status = RowDump ( SocketFD,
+ pPort,
+ "Data",
+ pBgrt->Length - sizeof ( *pBgrt ) + 1,
+ (UINT8 *)( pBgrt + 1 ));
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Build the table trailer
+ //
+ Status = TableTrailer ( SocketFD,
+ pPort,
+ pbDone );
+ break;
+ }
+
+ //
+ // Return the operation status
+ //
+ DBG_EXIT_STATUS ( Status );
+ return Status;
+}
+
+
+/**
+ Respond with the ACPI DSDT table
+
+ @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
+AcpiDsdtPage (
+ IN int SocketFD,
+ IN WSDT_PORT * pPort,
+ OUT BOOLEAN * pbDone
+ )
+{
+ CONST ACPI_DSDT * pDsdt;
+ CONST ACPI_FADT * pFadt;
+ EFI_STATUS Status;
+
+ DBG_ENTER ( );
+
+ //
+ // Send the DADT page
+ //
+ for ( ; ; ) {
+ //
+ // Locate the DADT
+ //
+ pFadt = (ACPI_FADT *)LocateTable ( FADT_SIGNATURE );
+ if ( NULL == pFadt ) {
+ Status = EFI_NOT_FOUND;
+ break;
+ }
+ pDsdt = (VOID *)(UINTN)pFadt->XDsdt;
+
+ //
+ // Send the page and table header
+ //
+ Status = TableHeader ( SocketFD, pPort, L"DSDT - Differentiated System Description Table", pDsdt );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Display the DSDT header
+ //
+ Status = RowAnsiArray ( SocketFD,
+ pPort,
+ "Signature",
+ sizeof ( pDsdt->Signature ),
+ (CHAR8 *)&pDsdt->Signature );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowDecimalValue ( SocketFD,
+ pPort,
+ "Length",
+ pDsdt->Length );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowDecimalValue ( SocketFD,
+ pPort,
+ "Revision",
+ pDsdt->Revision );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowHexValue ( SocketFD,
+ pPort,
+ "Checksum",
+ pDsdt->Checksum,
+ NULL );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowAnsiArray ( SocketFD,
+ pPort,
+ "OEMID",
+ sizeof ( pDsdt->OemId ),
+ (CONST CHAR8 *)&pDsdt->OemId[ 0 ]);
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowAnsiArray ( SocketFD,
+ pPort,
+ "OEM Table ID",
+ sizeof ( pDsdt->OemTableId ),
+ (CONST CHAR8 *)&pDsdt->OemTableId[ 0 ]);
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowRevision ( SocketFD,
+ pPort,
+ "OEM Revision",
+ pDsdt->OemRevision );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowAnsiArray ( SocketFD,
+ pPort,
+ "Creator ID",
+ sizeof ( pDsdt->CreatorId ),
+ (CHAR8 *)&pDsdt->CreatorId );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowRevision ( SocketFD,
+ pPort,
+ "Creator Revision",
+ pDsdt->CreatorRevision );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Display the data from the DSDT
+ //
+ Status = RowDump ( SocketFD,
+ pPort,
+ "Definition Block",
+ pDsdt->Length - sizeof ( *pDsdt ) + 1,
+ &pDsdt->DefinitionBlock[0]);
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Build the table trailer
+ //
+ Status = TableTrailer ( SocketFD,
+ pPort,
+ pbDone );
+ break;
+ }
+
+ //
+ // Return the operation status
+ //
+ DBG_EXIT_STATUS ( Status );
+ return Status;
+}
+
+
+/**
+ Respond with the ACPI FADT table
+
+ @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
+AcpiFadtPage (
+ IN int SocketFD,
+ IN WSDT_PORT * pPort,
+ OUT BOOLEAN * pbDone
+ )
+{
+ CONST ACPI_FADT * pFadt;
+ EFI_STATUS Status;
+
+ DBG_ENTER ( );
+
+ //
+ // Send the FADT page
+ //
+ for ( ; ; ) {
+ //
+ // Locate the FADT
+ //
+ pFadt = (ACPI_FADT *)LocateTable ( FADT_SIGNATURE );
+ if ( NULL == pFadt ) {
+ Status = EFI_NOT_FOUND;
+ break;
+ }
+
+ //
+ // Send the page and table header
+ //
+ Status = TableHeader ( SocketFD, pPort, L"FADT - Fixed ACPI Description Table", pFadt );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Display the FSDT header
+ //
+ Status = RowAnsiArray ( SocketFD,
+ pPort,
+ "Signature",
+ sizeof ( pFadt->Signature ),
+ (CHAR8 *)&pFadt->Signature );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowDecimalValue ( SocketFD,
+ pPort,
+ "Length",
+ pFadt->Length );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowDecimalValue ( SocketFD,
+ pPort,
+ "Revision",
+ pFadt->Revision );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowHexValue ( SocketFD,
+ pPort,
+ "Checksum",
+ pFadt->Checksum,
+ NULL );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowAnsiArray ( SocketFD,
+ pPort,
+ "OEMID",
+ sizeof ( pFadt->OemId ),
+ (CONST CHAR8 *)&pFadt->OemId[ 0 ]);
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowAnsiArray ( SocketFD,
+ pPort,
+ "OEM Table ID",
+ sizeof ( pFadt->OemTableId ),
+ (CONST CHAR8 *)&pFadt->OemTableId[ 0 ]);
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowRevision ( SocketFD,
+ pPort,
+ "OEM Revision",
+ pFadt->OemRevision );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowAnsiArray ( SocketFD,
+ pPort,
+ "Creator ID",
+ sizeof ( pFadt->CreatorId ),
+ (CHAR8 *)&pFadt->CreatorId );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowRevision ( SocketFD,
+ pPort,
+ "Creator Revision",
+ pFadt->CreatorRevision );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Display the data from the FADT
+ //
+ Status = RowPointer ( SocketFD,
+ pPort,
+ "FIRMWARE_CTRL",
+ (CONST VOID *)(UINTN)pFadt->FirmwareCtrl,
+ NULL );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowPointer ( SocketFD,
+ pPort,
+ "DSDT",
+ (CONST VOID *)(UINTN)pFadt->DSDT,
+ ( pFadt->DSDT == pFadt->XDsdt ) ? PAGE_ACPI_DSDT : NULL );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowHexValue ( SocketFD,
+ pPort,
+ "Reserved",
+ pFadt->Reserved,
+ NULL );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowHexValue ( SocketFD,
+ pPort,
+ "Preferred_PM_Profile",
+ pFadt->PreferredPmProfile,
+ NULL );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowHexValue ( SocketFD,
+ pPort,
+ "SCI_INT",
+ pFadt->SciInt,
+ NULL );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowHexValue ( SocketFD,
+ pPort,
+ "SMI_CMD",
+ pFadt->SmiCmd,
+ NULL );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowHexValue ( SocketFD,
+ pPort,
+ "ACPI_ENABLE",
+ pFadt->AcpiEnable,
+ NULL );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowHexValue ( SocketFD,
+ pPort,
+ "ACPI_DISABLE",
+ pFadt->AcpiDisable,
+ NULL );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowHexValue ( SocketFD,
+ pPort,
+ "S4BIOS_REQ",
+ pFadt->S4BiosReq,
+ NULL );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowHexValue ( SocketFD,
+ pPort,
+ "PSTATE_CNT",
+ pFadt->PStateCnt,
+ NULL );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowHexValue ( SocketFD,
+ pPort,
+ "PM1a_EVT_BLK",
+ pFadt->Pm1aEvtBlk,
+ NULL );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowHexValue ( SocketFD,
+ pPort,
+ "PM1b_EVT_BLK",
+ pFadt->Pm1bEvtBlk,
+ NULL );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowHexValue ( SocketFD,
+ pPort,
+ "PM1a_CNT_BLK",
+ pFadt->Pm1aCntBlk,
+ NULL );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowHexValue ( SocketFD,
+ pPort,
+ "PM1b_CNT_BLK",
+ pFadt->Pm1bCntBlk,
+ NULL );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowHexValue ( SocketFD,
+ pPort,
+ "PM2_CNT_BLK",
+ pFadt->Pm2CntBlk,
+ NULL );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowHexValue ( SocketFD,
+ pPort,
+ "PM_TMR_BLK",
+ pFadt->PmTmrBlk,
+ NULL );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ Status = RowHexValue ( SocketFD,
+ pPort,
+ "GPE0_BLK",
+ pFadt->Gpe0Blk,
+ NULL );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowHexValue ( SocketFD,
+ pPort,
+ "GPE1_BLK",
+ pFadt->Gpe1Blk,
+ NULL );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowDecimalValue ( SocketFD,
+ pPort,
+ "PM1_EVT_LEN",
+ pFadt->Pm1EvtLen );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowDecimalValue ( SocketFD,
+ pPort,
+ "PM1_CNT_LEN",
+ pFadt->Pm1CntLen );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowDecimalValue ( SocketFD,
+ pPort,
+ "PM2_CNT_LEN",
+ pFadt->PM2CntLen );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowDecimalValue ( SocketFD,
+ pPort,
+ "PM_TMR_LEN",
+ pFadt->PmTmrLen );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowDecimalValue ( SocketFD,
+ pPort,
+ "GPE0_BLK_LEN",
+ pFadt->Gpe0BlkLen );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowDecimalValue ( SocketFD,
+ pPort,
+ "GPE1_BLK_LEN",
+ pFadt->Gpe1BlkLen );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowHexValue ( SocketFD,
+ pPort,
+ "GPE1_BASE",
+ pFadt->Gpe1Base,
+ NULL );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowDecimalValue ( SocketFD,
+ pPort,
+ "CST_CNT",
+ pFadt->CstCnt );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowHexValue ( SocketFD,
+ pPort,
+ "P_LVL2_LAT",
+ pFadt->PLvl2Lat,
+ NULL );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowHexValue ( SocketFD,
+ pPort,
+ "P_LVL3_LAT",
+ pFadt->PLvl3Lat,
+ NULL );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowDecimalValue ( SocketFD,
+ pPort,
+ "FLUSH_SIZE",
+ pFadt->FlushSize );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowDecimalValue ( SocketFD,
+ pPort,
+ "FLUSH_Stride",
+ pFadt->FlushStride );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowHexValue ( SocketFD,
+ pPort,
+ "DUTY_OFFSET",
+ pFadt->DutyOffset,
+ NULL );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowHexValue ( SocketFD,
+ pPort,
+ "DUTY_WIDTH",
+ pFadt->DutyWidth,
+ NULL );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowHexValue ( SocketFD,
+ pPort,
+ "DAY_ALRM",
+ pFadt->DayAlrm,
+ NULL );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowHexValue ( SocketFD,
+ pPort,
+ "MON_ALRM",
+ pFadt->MonAlrm,
+ NULL );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowHexValue ( SocketFD,
+ pPort,
+ "CENTURY",
+ pFadt->Century,
+ NULL );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowHexValue ( SocketFD,
+ pPort,
+ "IAPC_BOOT_ARCH",
+ pFadt->IapcBootArch,
+ NULL );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowHexValue ( SocketFD,
+ pPort,
+ "Reserved",
+ pFadt->Reserved2,
+ NULL );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowHexValue ( SocketFD,
+ pPort,
+ "Flags",
+ pFadt->Flags,
+ NULL );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowGenericAddress ( SocketFD,
+ pPort,
+ "RESET_REG",
+ &pFadt->ResetReg[0],
+ NULL );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowHexValue ( SocketFD,
+ pPort,
+ "RESET_VALUE",
+ pFadt->ResetValue,
+ NULL );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowHexValue ( SocketFD,
+ pPort,
+ "Reserved",
+ pFadt->Reserved3[0],
+ NULL );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowHexValue ( SocketFD,
+ pPort,
+ "Reserved",
+ pFadt->Reserved3[1],
+ NULL );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowHexValue ( SocketFD,
+ pPort,
+ "Reserved",
+ pFadt->Reserved3[2],
+ NULL );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowHexValue ( SocketFD,
+ pPort,
+ "X_FIRMWARE_CTRL",
+ pFadt->XFirmwareCtrl,
+ NULL );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowHexValue ( SocketFD,
+ pPort,
+ "X_DSDT",
+ pFadt->XDsdt,
+ PAGE_ACPI_DSDT );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowGenericAddress ( SocketFD,
+ pPort,
+ "X_PM1a_EVT_BLK",
+ &pFadt->XPm1aEvtBlk[0],
+ NULL );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowGenericAddress ( SocketFD,
+ pPort,
+ "X_PM1b_EVT_BLK",
+ &pFadt->XPm1bEvtBlk[0],
+ NULL );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowGenericAddress ( SocketFD,
+ pPort,
+ "X_PM1a_CNT_BLK",
+ &pFadt->XPm1aCntBlk[0],
+ NULL );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowGenericAddress ( SocketFD,
+ pPort,
+ "X_PM1b_CNT_BLK",
+ &pFadt->XPm1bCntBlk[0],
+ NULL );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowGenericAddress ( SocketFD,
+ pPort,
+ "X_PM2_CNT_BLK",
+ &pFadt->XPm2CntBlk[0],
+ NULL );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowGenericAddress ( SocketFD,
+ pPort,
+ "X_PM_TMR_BLK",
+ &pFadt->XPmTmrBlk[0],
+ NULL );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowGenericAddress ( SocketFD,
+ pPort,
+ "X_GPE0_BLK",
+ &pFadt->XGpe0Blk[0],
+ NULL );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowGenericAddress ( SocketFD,
+ pPort,
+ "X_GPE1_BLK",
+ &pFadt->XGpe1Blk[0],
+ NULL );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Build the table trailer
+ //
+ Status = TableTrailer ( SocketFD,
+ pPort,
+ pbDone );
+ break;
+ }
+
+ //
+ // Return the operation status
+ //
+ DBG_EXIT_STATUS ( Status );
+ return Status;
+}
+
+
+/**
+ Respond with the HPET table
+
+ @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
+AcpiHpetPage (
+ IN int SocketFD,
+ IN WSDT_PORT * pPort,
+ OUT BOOLEAN * pbDone
+ )
+{
+ CONST ACPI_UNKNOWN * pHpet;
+ EFI_STATUS Status;
+
+ DBG_ENTER ( );
+
+ //
+ // Send the HPET page
+ //
+ for ( ; ; ) {
+ //
+ // Locate the HPET
+ //
+ pHpet = (ACPI_UNKNOWN *)LocateTable ( HPET_SIGNATURE );
+ if ( NULL == pHpet ) {
+ Status = EFI_NOT_FOUND;
+ break;
+ }
+
+ //
+ // Send the page and table header
+ //
+ Status = TableHeader ( SocketFD, pPort, L"HPET Table", pHpet );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Display the header
+ //
+ Status = RowAnsiArray ( SocketFD,
+ pPort,
+ "Signature",
+ sizeof ( pHpet->Signature ),
+ (CHAR8 *)&pHpet->Signature );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowDecimalValue ( SocketFD,
+ pPort,
+ "Length",
+ pHpet->Length );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Display the data from the table
+ //
+ Status = RowDump ( SocketFD,
+ pPort,
+ "Data",
+ pHpet->Length - sizeof ( *pHpet ) + 1,
+ (UINT8 *)( pHpet + 1 ));
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Build the table trailer
+ //
+ Status = TableTrailer ( SocketFD,
+ pPort,
+ pbDone );
+ break;
+ }
+
+ //
+ // Return the operation status
+ //
+ DBG_EXIT_STATUS ( Status );
+ return Status;
+}
+
+
+/**
+ Respond with the MCFG table
+
+ @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
+AcpiMcfgPage (
+ IN int SocketFD,
+ IN WSDT_PORT * pPort,
+ OUT BOOLEAN * pbDone
+ )
+{
+ CONST ACPI_UNKNOWN * pMcfg;
+ EFI_STATUS Status;
+
+ DBG_ENTER ( );
+
+ //
+ // Send the MCFG page
+ //
+ for ( ; ; ) {
+ //
+ // Locate the MCFG
+ //
+ pMcfg = (ACPI_UNKNOWN *)LocateTable ( MCFG_SIGNATURE );
+ if ( NULL == pMcfg ) {
+ Status = EFI_NOT_FOUND;
+ break;
+ }
+
+ //
+ // Send the page and table header
+ //
+ Status = TableHeader ( SocketFD, pPort, L"MCFG Table", pMcfg );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Display the header
+ //
+ Status = RowAnsiArray ( SocketFD,
+ pPort,
+ "Signature",
+ sizeof ( pMcfg->Signature ),
+ (CHAR8 *)&pMcfg->Signature );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowDecimalValue ( SocketFD,
+ pPort,
+ "Length",
+ pMcfg->Length );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Display the data from the table
+ //
+ Status = RowDump ( SocketFD,
+ pPort,
+ "Data",
+ pMcfg->Length - sizeof ( *pMcfg ) + 1,
+ (UINT8 *)( pMcfg + 1 ));
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Build the table trailer
+ //
+ Status = TableTrailer ( SocketFD,
+ pPort,
+ pbDone );
+ break;
+ }
+
+ //
+ // Return the operation status
+ //
+ DBG_EXIT_STATUS ( Status );
+ return Status;
+}
+
+
+/**
+ Respond with the ACPI RSDP 1.0b table
+
+ @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
+AcpiRsdp10Page (
+ IN int SocketFD,
+ IN WSDT_PORT * pPort,
+ OUT BOOLEAN * pbDone
+ )
+{
+ CONST EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER * pRsdp10b;
+ EFI_STATUS Status;
+
+ DBG_ENTER ( );
+
+ //
+ // Send the RSDP page
+ //
+ for ( ; ; ) {
+ //
+ // Locate the RSDP
+ //
+ Status = EfiGetSystemConfigurationTable ( &gEfiAcpi10TableGuid, (VOID **) &pRsdp10b );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Send the page and table header
+ //
+ Status = TableHeader ( SocketFD, pPort, L"RSDP - ACPI 1.0b Root System Description Pointer", pRsdp10b );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Display the RSDP
+ //
+ Status = RowAnsiArray ( SocketFD,
+ pPort,
+ "Signature",
+ sizeof ( pRsdp10b->Signature ),
+ (CHAR8 *)&pRsdp10b->Signature );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowHexValue ( SocketFD,
+ pPort,
+ "Checksum",
+ pRsdp10b->Checksum,
+ NULL );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowAnsiArray ( SocketFD,
+ pPort,
+ "OemId",
+ sizeof ( pRsdp10b->OemId ),
+ (CONST CHAR8 *)&pRsdp10b->OemId[ 0 ]);
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowHexValue ( SocketFD,
+ pPort,
+ "Reserved",
+ pRsdp10b->Reserved,
+ NULL );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowPointer ( SocketFD,
+ pPort,
+ "RsdtAddress",
+ (VOID *)(UINTN)pRsdp10b->RsdtAddress,
+ PAGE_ACPI_RSDT );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Build the table trailer
+ //
+ Status = TableTrailer ( SocketFD,
+ pPort,
+ pbDone );
+ break;
+ }
+
+ //
+ // Return the operation status
+ //
+ DBG_EXIT_STATUS ( Status );
+ return Status;
+}
+
+
+/**
+ Respond with the ACPI RSDP 3.0 table
+
+ @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
+AcpiRsdp30Page (
+ IN int SocketFD,
+ IN WSDT_PORT * pPort,
+ OUT BOOLEAN * pbDone
+ )
+{
+ CONST EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER * pRsdp30;
+ EFI_STATUS Status;
+
+ DBG_ENTER ( );
+
+ //
+ // Send the RSDP page
+ //
+ for ( ; ; ) {
+ //
+ // Locate the RSDP
+ //
+ Status = EfiGetSystemConfigurationTable ( &gEfiAcpiTableGuid, (VOID **) &pRsdp30 );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Send the page and table header
+ //
+ Status = TableHeader ( SocketFD, pPort, L"RSDP - ACPI 3.0 Root System Description Pointer", pRsdp30 );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Display the RSDP
+ //
+ Status = RowAnsiArray ( SocketFD,
+ pPort,
+ "Signature",
+ sizeof ( pRsdp30->Signature ),
+ (CHAR8 *)&pRsdp30->Signature );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowHexValue ( SocketFD,
+ pPort,
+ "Checksum",
+ pRsdp30->Checksum,
+ NULL );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowAnsiArray ( SocketFD,
+ pPort,
+ "OemId",
+ sizeof ( pRsdp30->OemId ),
+ (CONST CHAR8 *)&pRsdp30->OemId[ 0 ]);
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowHexValue ( SocketFD,
+ pPort,
+ "Revision",
+ pRsdp30->Revision,
+ NULL );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowPointer ( SocketFD,
+ pPort,
+ "RsdtAddress",
+ (VOID *)(UINTN)pRsdp30->RsdtAddress,
+ PAGE_ACPI_RSDT );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowDecimalValue ( SocketFD,
+ pPort,
+ "Length",
+ pRsdp30->Length );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowPointer ( SocketFD,
+ pPort,
+ "XsdtAddress",
+ (VOID *)(UINTN)pRsdp30->XsdtAddress,
+ NULL );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowHexValue ( SocketFD,
+ pPort,
+ "ExtendedChecksum",
+ pRsdp30->ExtendedChecksum,
+ NULL );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowBytes ( SocketFD,
+ pPort,
+ "Reserved",
+ sizeof ( pRsdp30->Reserved ),
+ &pRsdp30->Reserved[ 0 ]);
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Build the table trailer
+ //
+ Status = TableTrailer ( SocketFD,
+ pPort,
+ pbDone );
+ break;
+ }
+
+ //
+ // Return the operation status
+ //
+ DBG_EXIT_STATUS ( Status );
+ return Status;
+}
+
+
+/**
+ Respond with the ACPI RSDT table
+
+ @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
+AcpiRsdtPage (
+ IN int SocketFD,
+ IN WSDT_PORT * pPort,
+ OUT BOOLEAN * pbDone
+ )
+{
+ CONST UINT32 * pEnd;
+ CONST UINT32 * pEntry;
+ CONST ACPI_RSDT * pRsdt;
+ CONST CHAR8 * pTableName;
+ CONST CHAR16 * pWebPage;
+ EFI_STATUS Status;
+ UINT32 TableName[ 2 ];
+
+ DBG_ENTER ( );
+
+ //
+ // Send the RSDT page
+ //
+ for ( ; ; ) {
+ //
+ // Locate the RSDT
+ //
+ pRsdt = LocateRsdt ( );
+ if ( NULL == pRsdt ) {
+ Status = EFI_NOT_FOUND;
+ break;
+ }
+
+ //
+ // Send the page and table header
+ //
+ Status = TableHeader ( SocketFD, pPort, L"RSDT - ACPI Root System Description Table", pRsdt );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Display the RSDT
+ //
+ Status = RowAnsiArray ( SocketFD,
+ pPort,
+ "Signature",
+ sizeof ( pRsdt->Signature ),
+ (CHAR8 *)&pRsdt->Signature );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowDecimalValue ( SocketFD,
+ pPort,
+ "Length",
+ pRsdt->Length );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowDecimalValue ( SocketFD,
+ pPort,
+ "Revision",
+ pRsdt->Revision );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowHexValue ( SocketFD,
+ pPort,
+ "Checksum",
+ pRsdt->Checksum,
+ NULL );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowAnsiArray ( SocketFD,
+ pPort,
+ "OEMID",
+ sizeof ( pRsdt->OemId ),
+ (CONST CHAR8 *)&pRsdt->OemId[ 0 ]);
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowAnsiArray ( SocketFD,
+ pPort,
+ "OEM Table ID",
+ sizeof ( pRsdt->OemTableId ),
+ (CONST CHAR8 *)&pRsdt->OemTableId[ 0 ]);
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowRevision ( SocketFD,
+ pPort,
+ "OEM Revision",
+ pRsdt->OemRevision );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowAnsiArray ( SocketFD,
+ pPort,
+ "Creator ID",
+ sizeof ( pRsdt->CreatorId ),
+ (CHAR8 *)&pRsdt->CreatorId );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowRevision ( SocketFD,
+ pPort,
+ "Creator Revision",
+ pRsdt->CreatorRevision );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Walk the list of entries
+ //
+ pEntry = &pRsdt->Entry[ 0 ];
+ pEnd = &pEntry[(( pRsdt->Length - sizeof ( *pRsdt )) >> 2 ) + 1 ];
+ TableName[ 1 ] = 0;
+ while ( pEnd > pEntry ) {
+ //
+ // The entry is actually a 32-bit physical table address
+ // The first entry in the table is the 32-bit table signature
+ //
+ TableName[ 0 ] = *(UINT32 *)(UINTN)*pEntry;
+ pWebPage = SignatureLookup ( &TableName[ 0 ], &pTableName );
+
+ //
+ // Display the table address
+ //
+ Status = RowPointer ( SocketFD,
+ pPort,
+ pTableName,
+ (VOID *)(UINTN)*pEntry,
+ pWebPage );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ pEntry++;
+ }
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Build the table trailer
+ //
+ Status = TableTrailer ( SocketFD,
+ pPort,
+ pbDone );
+ break;
+ }
+
+ //
+ // Return the operation status
+ //
+ DBG_EXIT_STATUS ( Status );
+ return Status;
+}
+
+
+/**
+ Respond with the SSDT table
+
+ @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
+AcpiSsdtPage (
+ IN int SocketFD,
+ IN WSDT_PORT * pPort,
+ OUT BOOLEAN * pbDone
+ )
+{
+ CONST ACPI_UNKNOWN * pSsdt;
+ EFI_STATUS Status;
+
+ DBG_ENTER ( );
+
+ //
+ // Send the SSDT page
+ //
+ for ( ; ; ) {
+ //
+ // Locate the SSDT
+ //
+ pSsdt = (ACPI_UNKNOWN *)LocateTable ( SSDT_SIGNATURE );
+ if ( NULL == pSsdt ) {
+ Status = EFI_NOT_FOUND;
+ break;
+ }
+
+ //
+ // Send the page and table header
+ //
+ Status = TableHeader ( SocketFD, pPort, L"SSDT Table", pSsdt );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Display the header
+ //
+ Status = RowAnsiArray ( SocketFD,
+ pPort,
+ "Signature",
+ sizeof ( pSsdt->Signature ),
+ (CHAR8 *)&pSsdt->Signature );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowDecimalValue ( SocketFD,
+ pPort,
+ "Length",
+ pSsdt->Length );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Display the data from the table
+ //
+ Status = RowDump ( SocketFD,
+ pPort,
+ "Data",
+ pSsdt->Length - sizeof ( *pSsdt ) + 1,
+ (UINT8 *)( pSsdt + 1 ));
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Build the table trailer
+ //
+ Status = TableTrailer ( SocketFD,
+ pPort,
+ pbDone );
+ break;
+ }
+
+ //
+ // Return the operation status
+ //
+ DBG_EXIT_STATUS ( Status );
+ return Status;
+}
+
+
+/**
+ Respond with the TCPA table
+
+ @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
+AcpiTcpaPage (
+ IN int SocketFD,
+ IN WSDT_PORT * pPort,
+ OUT BOOLEAN * pbDone
+ )
+{
+ CONST ACPI_UNKNOWN * pTcpa;
+ EFI_STATUS Status;
+
+ DBG_ENTER ( );
+
+ //
+ // Send the TCPA page
+ //
+ for ( ; ; ) {
+ //
+ // Locate the TCPA
+ //
+ pTcpa = (ACPI_UNKNOWN *)LocateTable ( TCPA_SIGNATURE );
+ if ( NULL == pTcpa ) {
+ Status = EFI_NOT_FOUND;
+ break;
+ }
+
+ //
+ // Send the page and table header
+ //
+ Status = TableHeader ( SocketFD, pPort, L"TCPA Table", pTcpa );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Display the header
+ //
+ Status = RowAnsiArray ( SocketFD,
+ pPort,
+ "Signature",
+ sizeof ( pTcpa->Signature ),
+ (CHAR8 *)&pTcpa->Signature );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowDecimalValue ( SocketFD,
+ pPort,
+ "Length",
+ pTcpa->Length );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Display the data from the table
+ //
+ Status = RowDump ( SocketFD,
+ pPort,
+ "Data",
+ pTcpa->Length - sizeof ( *pTcpa ) + 1,
+ (UINT8 *)( pTcpa + 1 ));
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Build the table trailer
+ //
+ Status = TableTrailer ( SocketFD,
+ pPort,
+ pbDone );
+ break;
+ }
+
+ //
+ // Return the operation status
+ //
+ DBG_EXIT_STATUS ( Status );
+ return Status;
+}
+
+
+/**
+ Respond with the UEFI table
+
+ @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
+AcpiUefiPage (
+ IN int SocketFD,
+ IN WSDT_PORT * pPort,
+ OUT BOOLEAN * pbDone
+ )
+{
+ CONST ACPI_UNKNOWN * pUefi;
+ EFI_STATUS Status;
+
+ DBG_ENTER ( );
+
+ //
+ // Send the UEFI page
+ //
+ for ( ; ; ) {
+ //
+ // Locate the UEFI
+ //
+ pUefi = (ACPI_UNKNOWN *)LocateTable ( UEFI_SIGNATURE );
+ if ( NULL == pUefi ) {
+ Status = EFI_NOT_FOUND;
+ break;
+ }
+
+ //
+ // Send the page and table header
+ //
+ Status = TableHeader ( SocketFD, pPort, L"UEFI Table", pUefi );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Display the header
+ //
+ Status = RowAnsiArray ( SocketFD,
+ pPort,
+ "Signature",
+ sizeof ( pUefi->Signature ),
+ (CHAR8 *)&pUefi->Signature );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowDecimalValue ( SocketFD,
+ pPort,
+ "Length",
+ pUefi->Length );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Display the data from the table
+ //
+ Status = RowDump ( SocketFD,
+ pPort,
+ "Data",
+ pUefi->Length - sizeof ( *pUefi ) + 1,
+ (UINT8 *)( pUefi + 1 ));
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Build the table trailer
+ //
+ Status = TableTrailer ( SocketFD,
+ pPort,
+ pbDone );
+ break;
+ }
+
+ //
+ // Return the operation status
+ //
+ DBG_EXIT_STATUS ( Status );
+ return Status;
+}
diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/WebServer/BootServicesTable.c b/uefi/linaro-edk2/AppPkg/Applications/Sockets/WebServer/BootServicesTable.c
new file mode 100644
index 0000000..4fc1324
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/WebServer/BootServicesTable.c
@@ -0,0 +1,471 @@
+/**
+ @file
+ Display the boot services table
+
+ Copyright (c) 2011-2012, Intel Corporation
+ All rights reserved. This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <WebServer.h>
+
+/**
+ Respond with the boot services table
+
+ @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
+BootServicesTablePage (
+ IN int SocketFD,
+ IN WSDT_PORT * pPort,
+ OUT BOOLEAN * pbDone
+ )
+{
+ EFI_STATUS Status;
+
+ DBG_ENTER ( );
+
+ //
+ // Send the boot services page
+ //
+ for ( ; ; ) {
+ //
+ // Send the page and table header
+ //
+ Status = TableHeader ( SocketFD, pPort, L"Boot Services Table", gBS );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ ///
+ /// The table header for the EFI Boot Services Table.
+ ///
+ Status = EfiTableHeader ( SocketFD,
+ pPort,
+ &gBS->Hdr );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Task Priority Services
+ //
+ Status = RowPointer ( SocketFD,
+ pPort,
+ "RaiseTPL",
+ (CONST VOID *)gBS->RaiseTPL,
+ NULL );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowPointer ( SocketFD,
+ pPort,
+ "RestoreTPL",
+ (CONST VOID *)gBS->RestoreTPL,
+ NULL );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Memory Services
+ //
+ Status = RowPointer ( SocketFD,
+ pPort,
+ "AllocatePages",
+ (CONST VOID *)gBS->AllocatePages,
+ NULL );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowPointer ( SocketFD,
+ pPort,
+ "FreePages",
+ (CONST VOID *)gBS->FreePages,
+ NULL );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowPointer ( SocketFD,
+ pPort,
+ "GetMemoryMap",
+ (CONST VOID *)gBS->GetMemoryMap,
+ NULL );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowPointer ( SocketFD,
+ pPort,
+ "AllocatePool",
+ (CONST VOID *)gBS->AllocatePool,
+ NULL );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowPointer ( SocketFD,
+ pPort,
+ "FreePool",
+ (CONST VOID *)gBS->FreePool,
+ NULL );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Event & Timer Services
+ //
+ Status = RowPointer ( SocketFD,
+ pPort,
+ "CreateEvent",
+ (CONST VOID *)gBS->CreateEvent,
+ NULL );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowPointer ( SocketFD,
+ pPort,
+ "SetTimer",
+ (CONST VOID *)gBS->SetTimer,
+ NULL );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowPointer ( SocketFD,
+ pPort,
+ "WaitForEvent",
+ (CONST VOID *)gBS->WaitForEvent,
+ NULL );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowPointer ( SocketFD,
+ pPort,
+ "SignalEvent",
+ (CONST VOID *)gBS->SignalEvent,
+ NULL );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowPointer ( SocketFD,
+ pPort,
+ "CloseEvent",
+ (CONST VOID *)gBS->CloseEvent,
+ NULL );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowPointer ( SocketFD,
+ pPort,
+ "CheckEvent",
+ (CONST VOID *)gBS->CheckEvent,
+ NULL );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Protocol Handler Services
+ //
+ Status = RowPointer ( SocketFD,
+ pPort,
+ "InstallProtocolInterface",
+ (CONST VOID *)gBS->InstallProtocolInterface,
+ NULL );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowPointer ( SocketFD,
+ pPort,
+ "ReinstallProtocolInterface",
+ (CONST VOID *)gBS->ReinstallProtocolInterface,
+ NULL );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowPointer ( SocketFD,
+ pPort,
+ "UninstallProtocolInterface",
+ (CONST VOID *)gBS->UninstallProtocolInterface,
+ NULL );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowPointer ( SocketFD,
+ pPort,
+ "HandleProtocol",
+ (CONST VOID *)gBS->HandleProtocol,
+ NULL );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowPointer ( SocketFD,
+ pPort,
+ "Reserved",
+ (CONST VOID *)gBS->Reserved,
+ NULL );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowPointer ( SocketFD,
+ pPort,
+ "RegisterProtocolNotify",
+ (CONST VOID *)gBS->RegisterProtocolNotify,
+ NULL );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowPointer ( SocketFD,
+ pPort,
+ "LocateHandle",
+ (CONST VOID *)gBS->LocateHandle,
+ NULL );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowPointer ( SocketFD,
+ pPort,
+ "LocateDevicePath",
+ (CONST VOID *)gBS->LocateDevicePath,
+ NULL );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowPointer ( SocketFD,
+ pPort,
+ "InstallConfigurationTable",
+ (CONST VOID *)gBS->InstallConfigurationTable,
+ NULL );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Image Services
+ //
+ Status = RowPointer ( SocketFD,
+ pPort,
+ "LoadImage",
+ (CONST VOID *)gBS->LoadImage,
+ NULL );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowPointer ( SocketFD,
+ pPort,
+ "StartImage",
+ (CONST VOID *)gBS->StartImage,
+ NULL );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowPointer ( SocketFD,
+ pPort,
+ "Exit",
+ (CONST VOID *)gBS->Exit,
+ NULL );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowPointer ( SocketFD,
+ pPort,
+ "UnloadImage",
+ (CONST VOID *)gBS->UnloadImage,
+ NULL );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowPointer ( SocketFD,
+ pPort,
+ "ExitBootServices",
+ (CONST VOID *)gBS->ExitBootServices,
+ NULL );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Miscellaneous Services
+ //
+ Status = RowPointer ( SocketFD,
+ pPort,
+ "GetNextMonotonicCount",
+ (CONST VOID *)gBS->GetNextMonotonicCount,
+ NULL );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowPointer ( SocketFD,
+ pPort,
+ "Stall",
+ (CONST VOID *)gBS->Stall,
+ NULL );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowPointer ( SocketFD,
+ pPort,
+ "SetWatchdogTimer",
+ (CONST VOID *)gBS->SetWatchdogTimer,
+ NULL );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // DriverSupport Services
+ //
+ Status = RowPointer ( SocketFD,
+ pPort,
+ "ConnectController",
+ (CONST VOID *)gBS->ConnectController,
+ NULL );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowPointer ( SocketFD,
+ pPort,
+ "DisconnectController",
+ (CONST VOID *)gBS->DisconnectController,
+ NULL );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Open and Close Protocol Services
+ //
+ Status = RowPointer ( SocketFD,
+ pPort,
+ "OpenProtocol",
+ (CONST VOID *)gBS->OpenProtocol,
+ NULL );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowPointer ( SocketFD,
+ pPort,
+ "CloseProtocol",
+ (CONST VOID *)gBS->CloseProtocol,
+ NULL );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowPointer ( SocketFD,
+ pPort,
+ "OpenProtocolInformation",
+ (CONST VOID *)gBS->OpenProtocolInformation,
+ NULL );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Library Services
+ //
+ Status = RowPointer ( SocketFD,
+ pPort,
+ "ProtocolsPerHandle",
+ (CONST VOID *)gBS->ProtocolsPerHandle,
+ NULL );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowPointer ( SocketFD,
+ pPort,
+ "LocateHandleBuffer",
+ (CONST VOID *)gBS->LocateHandleBuffer,
+ NULL );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowPointer ( SocketFD,
+ pPort,
+ "LocateProtocol",
+ (CONST VOID *)gBS->LocateProtocol,
+ NULL );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowPointer ( SocketFD,
+ pPort,
+ "InstallMultipleProtocolInterfaces",
+ (CONST VOID *)gBS->InstallMultipleProtocolInterfaces,
+ NULL );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowPointer ( SocketFD,
+ pPort,
+ "UninstallMultipleProtocolInterfaces",
+ (CONST VOID *)gBS->UninstallMultipleProtocolInterfaces,
+ NULL );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // 32-bit CRC Services
+ //
+ Status = RowPointer ( SocketFD,
+ pPort,
+ "CalculateCrc32",
+ (CONST VOID *)gBS->CalculateCrc32,
+ NULL );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Miscellaneous Services
+ //
+ Status = RowPointer ( SocketFD,
+ pPort,
+ "CopyMem",
+ (CONST VOID *)gBS->CopyMem,
+ NULL );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowPointer ( SocketFD,
+ pPort,
+ "SetMem",
+ (CONST VOID *)gBS->SetMem,
+ NULL );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowPointer ( SocketFD,
+ pPort,
+ "CreateEventEx",
+ (CONST VOID *)gBS->CreateEventEx,
+ NULL );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Build the table trailer
+ //
+ Status = TableTrailer ( SocketFD,
+ pPort,
+ pbDone );
+ break;
+ }
+
+ //
+ // Return the operation status
+ //
+ DBG_EXIT_STATUS ( Status );
+ return Status;
+}
diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/WebServer/ConfigurationTable.c b/uefi/linaro-edk2/AppPkg/Applications/Sockets/WebServer/ConfigurationTable.c
new file mode 100644
index 0000000..f6303df
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/WebServer/ConfigurationTable.c
@@ -0,0 +1,370 @@
+/**
+ @file
+ Display the configuration table
+
+ Copyright (c) 2011-2012, Intel Corporation
+ All rights reserved. This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <WebServer.h>
+#include <Guid/Acpi.h>
+#include <Guid/DebugImageInfoTable.h>
+#include <Guid/DxeServices.h>
+#include <Guid/HobList.h>
+#include <Guid/MemoryTypeInformation.h>
+#include <Guid/LoadModuleAtFixedAddress.h>
+
+
+typedef struct {
+ CHAR16 * GuidName;
+ EFI_GUID * pGuid;
+ CHAR16 * pWebPage;
+} GUID_NAME;
+
+CONST GUID_NAME mGuidName[] = {
+ { L"gEfiAcpi10TableGuid", &gEfiAcpi10TableGuid, PAGE_ACPI_RSDP_10B },
+ { L"gEfiAcpiTableGuid", &gEfiAcpiTableGuid, PAGE_ACPI_RSDP_30 },
+ { L"gEfiDebugImageInfoTableGuid", &gEfiDebugImageInfoTableGuid, NULL },
+ { L"gEfiDxeServicesTableGuid", &gEfiDxeServicesTableGuid, PAGE_DXE_SERVICES_TABLE },
+ { L"gEfiHobListGuid", &gEfiHobListGuid, NULL },
+ { L"gEfiMemoryTypeInformationGuid", &gEfiMemoryTypeInformationGuid, NULL },
+ { L"gLoadFixedAddressConfigurationTableGuid", &gLoadFixedAddressConfigurationTableGuid, NULL }
+};
+
+/**
+ Display a row containing a GUID value
+
+ @param [in] SocketFD The socket's file descriptor to add to the list.
+ @param [in] pPort The WSDT_PORT structure address
+ @param [in] pName Address of a zero terminated name string
+ @param [in] pGuid Address of the GUID to display
+
+ @retval EFI_SUCCESS The request was successfully processed
+
+**/
+EFI_STATUS
+RowGuid (
+ IN int SocketFD,
+ IN WSDT_PORT * pPort,
+ IN CONST CHAR8 * pName,
+ IN CONST EFI_GUID * pGuid
+ )
+{
+ CONST GUID_NAME * pGuidName;
+ CONST GUID_NAME * pGuidNameEnd;
+ EFI_STATUS Status;
+ UINTN Value;
+
+ DBG_ENTER ( );
+
+ //
+ // Use for/break instead of goto
+ //
+ for ( ; ; ) {
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ "<tr><td>" );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ pName );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ "</td><td><code>" );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Determine if this is a known GUID
+ //
+ pGuidName = &mGuidName[0];
+ pGuidNameEnd = &pGuidName[ sizeof ( mGuidName ) / sizeof ( mGuidName[0])];
+ while ( pGuidNameEnd > pGuidName ) {
+ if ( CompareGuid ( pGuidName->pGuid, pGuid )) {
+ //
+ // Display the web link if available
+ //
+ if ( NULL != pGuidName->pWebPage ) {
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ "<a target=\"_blank\" href=\"" );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = HttpSendUnicodeString ( SocketFD,
+ pPort,
+ pGuidName->pWebPage );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ "\">" );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ }
+
+ //
+ // Display the GUID name
+ //
+ Status = HttpSendUnicodeString ( SocketFD,
+ pPort,
+ pGuidName->GuidName );
+
+ //
+ // Complete the web link if available
+ //
+ if ( NULL != pGuidName->pWebPage ) {
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ "</a>" );
+ }
+ break;
+ }
+
+ //
+ // Set the next GUID name
+ //
+ pGuidName += 1;
+ }
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Only if the entry is not known, display the GUID and type
+ //
+ if ( pGuidNameEnd <= pGuidName ) {
+ //
+ // Display the GUID
+ //
+ Status = HttpSendGuid ( SocketFD,
+ pPort,
+ pGuid );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Display the GUID type
+ //
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ "<br/><a target=\"_blank\" href=\"http://www.ietf.org/rfc/rfc4122.txt\">Guid Type</a>: " );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Value = pGuid->Data4[1];
+ Value >>= 5;
+ if ( 3 >= Value ) {
+ //
+ // Network type
+ //
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ "Network " );
+ }
+ else if ( 5 >= Value ) {
+ //
+ // Standard type
+ //
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ "Standard " );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Decode the standard type using RFC 4122
+ //
+ Value = pGuid->Data3;
+ Value >>= 12;
+ switch ( Value ) {
+ default:
+ //
+ // Display the MAC address
+ //
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ "Version " );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = HttpSendValue ( SocketFD,
+ pPort,
+ pGuid->Data3 >> 12 );
+ break;
+
+ case 1:
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ "MAC address" );
+ break;
+
+ case 2:
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ "DCE Security" );
+ break;
+
+ case 3:
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ "MD5 hash" );
+ break;
+
+ case 4:
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ "Random" );
+ break;
+
+ case 5:
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ "SHA-1 hash" );
+ break;
+ }
+ }
+ else if ( 6 == Value ) {
+ //
+ // Microsoft's Component Object Model (COM) type
+ //
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ "Microsoft COM" );
+ }
+ else {
+ //
+ // Reserved type
+ //
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ "Reserved" );
+ }
+ }
+
+ //
+ // Done with this entry
+ //
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ "</code></td></tr>\r\n" );
+ break;
+ }
+
+ //
+ // Return the operation status
+ //
+ DBG_EXIT_STATUS ( Status );
+ return Status;
+}
+
+
+/**
+ Respond with the configuration tables
+
+ @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
+ConfigurationTablePage (
+ IN int SocketFD,
+ IN WSDT_PORT * pPort,
+ OUT BOOLEAN * pbDone
+ )
+{
+ EFI_CONFIGURATION_TABLE * pEnd;
+ EFI_CONFIGURATION_TABLE * pTable;
+ EFI_STATUS Status;
+
+ DBG_ENTER ( );
+
+ //
+ // Send the system table page
+ //
+ for ( ; ; ) {
+ //
+ // Send the page and table header
+ //
+ Status = TableHeader ( SocketFD, pPort, L"Configuration Tables", gST );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Display the table size
+ //
+ Status = RowDecimalValue ( SocketFD,
+ pPort,
+ "Entries",
+ gST->NumberOfTableEntries );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Determine the location of the configuration tables
+ //
+ pTable = gST->ConfigurationTable;
+ pEnd = &pTable[ gST->NumberOfTableEntries ];
+ while ( pEnd > pTable ) {
+ Status = RowGuid ( SocketFD,
+ pPort,
+ "VendorGuid",
+ &pTable->VendorGuid );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowPointer ( SocketFD,
+ pPort,
+ "VendorTable",
+ (VOID *)pTable->VendorTable,
+ NULL );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Set the next row
+ //
+ pTable += 1;
+ }
+
+ //
+ // Build the table trailer
+ //
+ Status = TableTrailer ( SocketFD,
+ pPort,
+ pbDone );
+ break;
+ }
+
+ //
+ // Return the operation status
+ //
+ DBG_EXIT_STATUS ( Status );
+ return Status;
+}
diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/WebServer/DhcpOptions.c b/uefi/linaro-edk2/AppPkg/Applications/Sockets/WebServer/DhcpOptions.c
new file mode 100644
index 0000000..8eeff45
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/WebServer/DhcpOptions.c
@@ -0,0 +1,222 @@
+/** @file
+ Display the DHCP options
+
+ Copyright (c) 2011 - 2012, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+**/
+#include <WebServer.h>
+#include <Guid/DxeServices.h>
+#include <Pi/PiDxeCis.h>
+
+#include <Protocol/Dhcp4.h>
+#include <Protocol/ServiceBinding.h>
+
+/**
+ Respond with the DHCP options
+
+ @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
+DhcpOptionsPage (
+ IN int SocketFD,
+ IN WSDT_PORT * pPort,
+ OUT BOOLEAN * pbDone
+ )
+{
+// EFI_HANDLE Dhcp4Handle;
+ EFI_DHCP4_MODE_DATA Dhcp4Mode;
+ UINTN HandleCount;
+ EFI_DHCP4_PROTOCOL * pDhcp4;
+ EFI_DHCP4_PACKET * pDhcp4Packet;
+ EFI_HANDLE * pEnd;
+ EFI_HANDLE * pHandle;
+// EFI_SERVICE_BINDING_PROTOCOL * pService;
+ EFI_STATUS Status;
+
+ DBG_ENTER ( );
+
+ //
+ // Send the DHCP options
+ //
+ for ( ; ; ) {
+ //
+ // Send the page header
+ //
+ Status = HttpPageHeader ( SocketFD, pPort, L"DHCP Options" );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Build the header
+ //
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ "<h1>" );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = HttpSendUnicodeString ( SocketFD,
+ pPort,
+ L"DHCP Options" );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ "</h1>\r\n" );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Attempt to locate DHCP clients
+ //
+ Status = gBS->LocateHandleBuffer ( ByProtocol,
+// &gEfiDhcp4ServiceBindingProtocolGuid,
+ &gEfiDhcp4ProtocolGuid,
+ NULL,
+ &HandleCount,
+ &pHandle );
+ if ( EFI_ERROR ( Status )) {
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ "DHCP not in use" );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ }
+ else {
+ //
+ // Walk the list of handles
+ //
+ pEnd = &pHandle [ HandleCount ];
+ while ( pEnd > pHandle ) {
+/*
+ //
+ // Get the DHCP service binding
+ //
+ Status = gBS->OpenProtocol ( *pHandle,
+ &gEfiDhcp4ServiceBindingProtocolGuid,
+ &pService,
+ NULL,
+ gImageHandle,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL );
+ if ( EFI_ERROR ( Status )) {
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ "Failed to open gEfiDhcp4ServiceBindingProtocolGuid" );
+ break;
+ }
+
+ //
+ // Get the DHCP handle
+ //
+ Status = pService->CreateChild ( pService,
+ &Dhcp4Handle );
+ if ( EFI_ERROR ( Status )) {
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ "Failed to create DHCP4 child" );
+ }
+ else {
+*/
+ //
+ // Get the DHCP protocol
+ //
+ Status = gBS->OpenProtocol ( *pHandle,
+// Dhcp4Handle,
+ &gEfiDhcp4ProtocolGuid,
+ (VOID **)&pDhcp4,
+ NULL,
+ gImageHandle,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL );
+ if ( EFI_ERROR ( Status )) {
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ "Failed to open gEfiDhcp4ProtocolGuid" );
+ }
+ else {
+ //
+ // Get the DHCP packet
+ //
+ Status = pDhcp4->GetModeData ( pDhcp4,
+ &Dhcp4Mode );
+ if ( EFI_ERROR ( Status )) {
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ "Failed to get DHCP4 mode" );
+ }
+ else {
+ //
+ // Get the last packet
+ //
+ pDhcp4Packet = Dhcp4Mode.ReplyPacket;
+ if ( NULL == pDhcp4Packet ) {
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ "No DHCP reply received!<br/>DHCP Mode:<br/>" );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Display the DHCP mode data
+ //
+ Status = HttpSendDump ( SocketFD,
+ pPort,
+ sizeof ( Dhcp4Mode ),
+ (UINT8 *)&Dhcp4Mode );
+ }
+ else {
+ //
+ // Display the DHCP packet
+ //
+ Status = HttpSendDump ( SocketFD,
+ pPort,
+ pDhcp4Packet->Length,
+ (UINT8 *)&pDhcp4Packet->Dhcp4 );
+ }
+ }
+/*
+ }
+
+ //
+ // Done with the DHCP protocol
+ //
+ pService->DestroyChild ( pService,
+ Dhcp4Handle );
+*/
+ }
+
+ //
+ // Set the next service binding
+ //
+ pHandle += 1;
+ }
+ }
+
+ //
+ // Send the page trailer
+ //
+ Status = HttpPageTrailer ( SocketFD, pPort, pbDone );
+ break;
+ }
+
+ //
+ // Return the operation status
+ //
+ DBG_EXIT_STATUS ( Status );
+ return Status;
+}
diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/WebServer/DxeServicesTable.c b/uefi/linaro-edk2/AppPkg/Applications/Sockets/WebServer/DxeServicesTable.c
new file mode 100644
index 0000000..fe0f597
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/WebServer/DxeServicesTable.c
@@ -0,0 +1,232 @@
+/** @file
+ Display the DXE services table
+
+ Copyright (c) 2011 - 2012 Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+--*/
+#include <WebServer.h>
+#include <Guid/DxeServices.h>
+#include <Pi/PiDxeCis.h>
+
+/**
+ Respond with the DXE services table
+
+ @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
+DxeServicesTablePage (
+ IN int SocketFD,
+ IN WSDT_PORT * pPort,
+ OUT BOOLEAN * pbDone
+ )
+{
+ EFI_DXE_SERVICES * pDS;
+ EFI_STATUS Status;
+
+ DBG_ENTER ( );
+
+ //
+ // Send the DXE services page
+ //
+ for ( ; ; ) {
+ //
+ // Get the DXE services table
+ //
+ Status = EfiGetSystemConfigurationTable (&gEfiDxeServicesTableGuid, (VOID **) &pDS);
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Send the page and table header
+ //
+ Status = TableHeader ( SocketFD, pPort, L"DXE Services Table", pDS );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ ///
+ /// The table header for the DXE Services Table.
+ /// This header contains the DXE_SERVICES_SIGNATURE and DXE_SERVICES_REVISION values.
+ ///
+ Status = EfiTableHeader ( SocketFD,
+ pPort,
+ &pDS->Hdr );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Global Coherency Domain Services
+ //
+ Status = RowPointer ( SocketFD,
+ pPort,
+ "AddMemorySpace",
+ (VOID *)pDS->AddMemorySpace,
+ NULL );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowPointer ( SocketFD,
+ pPort,
+ "AllocateMemorySpace",
+ (VOID *)pDS->AllocateMemorySpace,
+ NULL );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowPointer ( SocketFD,
+ pPort,
+ "FreeMemorySpace",
+ (VOID *)pDS->FreeMemorySpace,
+ NULL );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowPointer ( SocketFD,
+ pPort,
+ "RemoveMemorySpace",
+ (VOID *)pDS->RemoveMemorySpace,
+ NULL );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowPointer ( SocketFD,
+ pPort,
+ "GetMemorySpaceDescriptor",
+ (VOID *)pDS->GetMemorySpaceDescriptor,
+ NULL );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowPointer ( SocketFD,
+ pPort,
+ "SetMemorySpaceAttributes",
+ (VOID *)pDS->SetMemorySpaceAttributes,
+ NULL );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowPointer ( SocketFD,
+ pPort,
+ "GetMemorySpaceMap",
+ (VOID *)pDS->GetMemorySpaceMap,
+ NULL );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowPointer ( SocketFD,
+ pPort,
+ "AddIoSpace",
+ (VOID *)pDS->AddIoSpace,
+ NULL );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowPointer ( SocketFD,
+ pPort,
+ "AllocateIoSpace",
+ (VOID *)pDS->AllocateIoSpace,
+ NULL );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowPointer ( SocketFD,
+ pPort,
+ "FreeIoSpace",
+ (VOID *)pDS->FreeIoSpace,
+ NULL );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowPointer ( SocketFD,
+ pPort,
+ "RemoveIoSpace",
+ (VOID *)pDS->RemoveIoSpace,
+ NULL );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowPointer ( SocketFD,
+ pPort,
+ "GetIoSpaceDescriptor",
+ (VOID *)pDS->GetIoSpaceDescriptor,
+ NULL );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowPointer ( SocketFD,
+ pPort,
+ "GetIoSpaceMap",
+ (VOID *)pDS->GetIoSpaceMap,
+ NULL );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Dispatcher Services
+ //
+ Status = RowPointer ( SocketFD,
+ pPort,
+ "Dispatch",
+ (VOID *)pDS->Dispatch,
+ NULL );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowPointer ( SocketFD,
+ pPort,
+ "Schedule",
+ (VOID *)pDS->Schedule,
+ NULL );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowPointer ( SocketFD,
+ pPort,
+ "Trust",
+ (VOID *)pDS->Trust,
+ NULL );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Service to process a single firmware volume found in a capsule
+ //
+ Status = RowPointer ( SocketFD,
+ pPort,
+ "ProcessFirmwareVolume",
+ (VOID *)pDS->ProcessFirmwareVolume,
+ NULL );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Build the table trailer
+ //
+ Status = TableTrailer ( SocketFD,
+ pPort,
+ pbDone );
+ break;
+ }
+
+ //
+ // Return the operation status
+ //
+ DBG_EXIT_STATUS ( Status );
+ return Status;
+}
diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/WebServer/Exit.c b/uefi/linaro-edk2/AppPkg/Applications/Sockets/WebServer/Exit.c
new file mode 100644
index 0000000..5ff09d3
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/WebServer/Exit.c
@@ -0,0 +1,82 @@
+/**
+ @file
+ Exit response page
+
+ Copyright (c) 2011-2012, Intel Corporation
+ All rights reserved. This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#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;
+}
diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/WebServer/Firmware.c b/uefi/linaro-edk2/AppPkg/Applications/Sockets/WebServer/Firmware.c
new file mode 100644
index 0000000..a29da5e
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/WebServer/Firmware.c
@@ -0,0 +1,96 @@
+/**
+ @file
+ Display the firmware
+
+ Copyright (c) 2011-2012, Intel Corporation
+ All rights reserved. This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <WebServer.h>
+
+
+/**
+ Respond with the firmware status
+
+ @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
+FirmwarePage (
+ IN int SocketFD,
+ IN WSDT_PORT * pPort,
+ OUT BOOLEAN * pbDone
+ )
+{
+ EFI_STATUS Status;
+
+ DBG_ENTER ( );
+
+ //
+ // Send the system table page
+ //
+ for ( ; ; ) {
+ //
+ // Send the page and table header
+ //
+ Status = TableHeader ( SocketFD, pPort, L"Firmware", NULL );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Display the firmware vendor and revision
+ //
+ Status = RowUnicodeString ( SocketFD,
+ pPort,
+ "Vendor",
+ gST->FirmwareVendor );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ Status = RowRevision ( SocketFD,
+ pPort,
+ "Revision",
+ gST->FirmwareRevision );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Display the UEFI version
+ //
+ Status = RowRevision ( SocketFD,
+ pPort,
+ "UEFI",
+ gST->Hdr.Revision );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Build the table trailer
+ //
+ Status = TableTrailer ( SocketFD,
+ pPort,
+ pbDone );
+ break;
+ }
+
+ //
+ // Return the operation status
+ //
+ DBG_EXIT_STATUS ( Status );
+ return Status;
+}
diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/WebServer/HTTP.c b/uefi/linaro-edk2/AppPkg/Applications/Sockets/WebServer/HTTP.c
new file mode 100644
index 0000000..fae1dd9
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/WebServer/HTTP.c
@@ -0,0 +1,1735 @@
+/**
+ @file
+ HTTP processing for the web server.
+
+ Copyright (c) 2011-2012, Intel Corporation
+ All rights reserved. This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <WebServer.h>
+
+
+/**
+ Get a UTF-8 character from the buffer
+
+ @param [in] pData The address of the buffer containing the character
+ @param [out] ppData The address to receive the next character address
+
+ @return The character value
+
+**/
+INTN
+HttpCharGet (
+ IN UINT8 * pData,
+ IN UINT8 ** ppData
+ )
+{
+ INTN Data;
+ INTN Character;
+ INTN Control;
+ INTN Mask;
+
+ //
+ // Verify that there is some data left
+ //
+ if ( NULL == pData ) {
+ //
+ // No data to return
+ //
+ pData = NULL;
+ Character = 0;
+ }
+ else {
+ //
+ // Get the first portion of the character
+ //
+ Character = *pData++;
+ Control = Character;
+ Mask = 0xc0;
+
+ //
+ // Append the rest of the character
+ //
+ if ( 0 != ( Control & 0x80 )) {
+ while ( 0 != ( Control & 0x40 )) {
+ Character &= Mask;
+ Mask <<= 5;
+ Control <<= 1;
+ Character <<= 6;
+ Data = *pData++ & 0x3f;
+ if ( 0x80 != ( Data & 0xc0 )) {
+ //
+ // Invalid character
+ //
+ pData = NULL;
+ Character = 0;
+ break;
+ }
+ Character |= Data & 0x3f;
+ }
+ }
+ }
+
+ //
+ // Return the next character location and the character
+ //
+ *ppData = pData;
+ return Character;
+}
+
+
+/**
+ Transmit a portion of the HTTP response
+
+ @param [in] SocketFD The socket's file descriptor to add to the list.
+ @param [in] pPort The WSDT_PORT structure address
+
+ @retval EFI_SUCCESS The request was successfully processed
+
+**/
+EFI_STATUS
+HttpFlush (
+ IN int SocketFD,
+ IN WSDT_PORT * pPort
+ )
+{
+ INTN LengthInBytes;
+ UINT8 * pBuffer;
+ EFI_STATUS Status;
+
+ DBG_ENTER ( );
+
+ //
+ // Assume success
+ //
+ Status = EFI_SUCCESS;
+ pBuffer = &pPort->TxBuffer[0];
+ do {
+ //
+ // Attempt to send the data
+ //
+ LengthInBytes = send ( SocketFD,
+ pBuffer,
+ pPort->TxBytes,
+ 0 );
+ if ( -1 != LengthInBytes ) {
+ //
+ // Account for the data sent
+ //
+ pBuffer += LengthInBytes;
+ pPort->TxBytes -= LengthInBytes;
+ }
+ else {
+ //
+ // Transmit error
+ //
+ Status = EFI_DEVICE_ERROR;
+ break;
+ }
+ } while ( 0 < pPort->TxBytes );
+
+ //
+ // Return the operation status
+ //
+ DBG_EXIT_STATUS ( Status );
+ return Status;
+}
+
+
+/**
+ Convert the ANSI character to lower case
+
+ @param [in] Character The character to convert to lower case.
+
+ @return The lower case character
+
+**/
+INTN
+HttpLowerCase (
+ IN INTN Character
+ )
+{
+ //
+ // Determine if the character is upper case
+ //
+ if (( 'A' <= Character ) && ( 'Z' >= Character )) {
+ Character += 'a' - 'A';
+ }
+
+ //
+ // Return the lower case value of the character
+ //
+ return Character;
+}
+
+
+/**
+ Match a Unicode string against a UTF-8 string
+
+ @param [in] pString A zero terminated Unicode string
+ @param [in] pData A zero terminated UTF-8 string
+ @param [in] bIgnoreCase TRUE if case is to be ignored
+
+ @return The difference between the last two characters tested.
+ Returns -1 for error.
+
+**/
+INTN
+HttpMatch (
+ IN UINT16 * pString,
+ IN UINT8 * pData,
+ IN BOOLEAN bIgnoreCase
+ )
+{
+ INTN Character1;
+ INTN Character2;
+ INTN Difference;
+
+ do {
+ //
+ // Get the character from the comparison string
+ //
+ Character1 = *pString++;
+
+ //
+ // Convert the character to lower case
+ //
+ if ( bIgnoreCase ) {
+ Character1 = HttpLowerCase ( Character1 );
+ }
+
+ //
+ // Get the character from the request
+ //
+ Character2 = HttpCharGet ( pData, &pData );
+ if ( NULL == pData ) {
+ //
+ // Error getting character
+ //
+ Difference = -1;
+ break;
+ }
+
+ //
+ // Convert the character to lower case
+ //
+ if ( bIgnoreCase ) {
+ Character2 = HttpLowerCase ( Character2 );
+ }
+
+ //
+ // Compare the characters
+ //
+ Difference = Character1 - Character2;
+ if ( 0 != Difference ) {
+ return Difference;
+ }
+ } while ( 0 != Character1 );
+
+ //
+ // Return the difference
+ //
+ return Difference;
+}
+
+
+/**
+ Buffer the HTTP page header
+
+ @param [in] SocketFD The socket's file descriptor to add to the list.
+ @param [in] pPort The WSDT_PORT structure address
+ @param [in] pTitle A zero terminated Unicode title string
+
+ @retval EFI_SUCCESS The request was successfully processed
+
+**/
+EFI_STATUS
+HttpPageHeader (
+ IN int SocketFD,
+ IN WSDT_PORT * pPort,
+ IN CONST CHAR16 * pTitle
+ )
+{
+ EFI_STATUS Status;
+
+ DBG_ENTER ( );
+
+ //
+ // Build the page header
+ //
+ for ( ; ; ) {
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ "<!DOCTYPE "
+ "HTML "
+ "PUBLIC "
+ "\"-//W3C//DTD HTML 4.01 Transitional//EN\" "
+ "\"http://www.w3.org/TR/html4/loose.dtd\">\r\n" );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = HttpSendAnsiString ( SocketFD, pPort, "<html lang=\"en-US\">\r\n" );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ if ( NULL != pTitle ) {
+ Status = HttpSendAnsiString ( SocketFD, pPort, " <head>\r\n" );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = HttpSendAnsiString ( SocketFD, pPort, " <title>" );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = HttpSendUnicodeString ( SocketFD, pPort, pTitle );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = HttpSendAnsiString ( SocketFD, pPort, "</title>\r\n" );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = HttpSendAnsiString ( SocketFD, pPort, " </head>\r\n" );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ }
+ Status = HttpSendAnsiString ( SocketFD, pPort, " <body>\r\n" );
+ break;
+ }
+
+ //
+ // Return the operation status
+ //
+ DBG_EXIT_STATUS ( Status );
+ return Status;
+}
+
+
+/**
+ Respond with an error indicating that the page was not found
+
+ @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
+HttpPageNotFound (
+ IN int SocketFD,
+ IN WSDT_PORT * pPort,
+ IN BOOLEAN * pbDone
+ )
+{
+ EFI_STATUS Status;
+
+ DBG_ENTER ( );
+
+ //
+ // Send the page not found
+ //
+ for ( ; ; ) {
+ //
+ // Send the page header
+ //
+ Status = HttpPageHeader ( SocketFD, pPort, L"404 Not found" );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Send the page body
+ //
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ "ERROR <b>404</b><br />"
+ "Requested page is not available\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;
+}
+
+
+/**
+ Buffer and send the HTTP page trailer
+
+ @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
+HttpPageTrailer (
+ IN int SocketFD,
+ IN WSDT_PORT * pPort,
+ IN BOOLEAN * pbDone
+ )
+{
+ int RetVal;
+ EFI_STATUS Status;
+ socklen_t LengthInBytes;
+ struct sockaddr_in6 LocalAddress;
+ struct sockaddr_in6 RemoteAddress;
+
+ DBG_ENTER ( );
+
+ //
+ // Build the page header
+ //
+ for ( ; ; ) {
+ 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<code>" );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Display the system addresses and the page transfer direction
+ //
+ Status = HttpSendIpAddress ( SocketFD, pPort, &LocalAddress );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = HttpSendAnsiString ( SocketFD, pPort, " --> " );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = HttpSendIpAddress ( SocketFD, pPort, &RemoteAddress );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = HttpSendAnsiString ( SocketFD, pPort, "</code>\r\n" );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ }
+ }
+
+ //
+ // Terminate the page
+ //
+ Status = HttpSendAnsiString ( SocketFD, pPort, " </body>\r\n" );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = HttpSendAnsiString ( SocketFD, pPort, " </html>\r\n" );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Send the page trailer
+ //
+ Status = HttpFlush ( SocketFD, pPort );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Mark the page as complete
+ //
+ *pbDone = TRUE;
+ break;
+ }
+
+ //
+ // Return the operation status
+ //
+ DBG_EXIT_STATUS ( Status );
+ return Status;
+}
+
+
+/**
+ Replace a space with a zero
+
+ @param [in] pData The request buffer address
+ @param [in] pEnd End of buffer address
+
+ @return The next character location
+
+**/
+UINT8 *
+HttpReplaceSpace (
+ IN UINT8 * pData,
+ IN UINT8 * pEnd
+ )
+{
+ INTN Character;
+ UINT8 * pSpace;
+
+ pSpace = pData;
+ while ( pEnd > pData ) {
+ //
+ // Get the character from the request
+ //
+ Character = HttpCharGet ( pData, &pData );
+ if ( ' ' == Character ) {
+ break;
+ }
+ pSpace = pData;
+ }
+
+ //
+ // Replace the space character with zero
+ //
+ ZeroMem ( pSpace, pData - pSpace );
+
+ //
+ // Return the next character location
+ //
+ return pData;
+}
+
+
+/**
+ Process an HTTP request
+
+ @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
+HttpRequest (
+ IN int SocketFD,
+ IN WSDT_PORT * pPort,
+ OUT BOOLEAN * pbDone
+ )
+{
+ UINT8 * pData;
+ UINT8 * pEnd;
+ CONST DT_PAGE * pPage;
+ CONST DT_PAGE * pPageEnd;
+ UINT8 * pVerb;
+ UINT8 * pVersion;
+ UINT8 * pWebPage;
+ EFI_STATUS Status;
+
+ DBG_ENTER ( );
+
+ //
+ // Assume the request is not finished
+ //
+ *pbDone = FALSE;
+ Status = EFI_SUCCESS;
+ for ( ; ; ) {
+
+ //
+ // Attempt to parse the command
+ //
+ pData = &pPort->Request[0];
+ pEnd = &pData[ pPort->RequestLength ];
+ pVerb = pData;
+ pWebPage = HttpReplaceSpace ( pVerb, pEnd );
+ if ( pEnd <= pWebPage ) {
+ break;
+ }
+ pVersion = HttpReplaceSpace ( pWebPage, pEnd );
+ if ( pEnd <= pVersion ) {
+ break;
+ }
+
+ //
+ // Validate the request
+ //
+ if ( 0 != HttpMatch ( L"GET", pVerb, TRUE )) {
+ //
+ // Invalid request type
+ //
+ DEBUG (( DEBUG_REQUEST,
+ "HTTP: Invalid verb\r\n" ));
+ Status = EFI_NOT_FOUND;
+ break;
+ }
+
+ //
+ // Walk the page table
+ //
+ pPage = &mPageList[0];
+ pPageEnd = &pPage[ mPageCount ];
+ while ( pPageEnd > pPage ) {
+ //
+ // Determine if the page was located
+ //
+ if ( 0 == HttpMatch ( pPage->pPageName, pWebPage, FALSE )) {
+ break;
+ }
+
+ //
+ // Set the next page
+ //
+ pPage += 1;
+ }
+ if ( pPageEnd <= pPage ) {
+ //
+ // The page was not found
+ //
+ DEBUG (( DEBUG_REQUEST,
+ "HTTP: Page not found in page table\r\n" ));
+ Status = EFI_NOT_FOUND;
+ break;
+ }
+
+ //
+ // Respond with the page contents
+ //
+ Status = pPage->pfnResponse ( SocketFD, pPort, pbDone );
+ break;
+ }
+
+ //
+ // Return page not found if necessary
+ //
+ if ( EFI_NOT_FOUND == Status ) {
+ Status = HttpPageNotFound ( SocketFD, pPort, pbDone );
+ }
+
+ //
+ // Return the operation status
+ //
+ DBG_EXIT_STATUS ( Status );
+ return Status;
+}
+
+
+/**
+ Buffer data for sending
+
+ @param [in] SocketFD The socket's file descriptor to add to the list.
+ @param [in] pPort The WSDT_PORT structure address
+ @param [in] LengthInBytes Length of valid data in the buffer
+ @param [in] pBuffer Buffer of data to send
+
+ @retval EFI_SUCCESS The request was successfully processed
+
+**/
+EFI_STATUS
+HttpSend (
+ IN int SocketFD,
+ IN WSDT_PORT * pPort,
+ IN size_t LengthInBytes,
+ IN CONST UINT8 * pBuffer
+ )
+{
+ size_t DataBytes;
+ size_t MaxBytes;
+ EFI_STATUS Status;
+
+ //
+ // Assume success
+ //
+ Status = EFI_SUCCESS;
+ do {
+ //
+ // Determine how much data fits into the buffer
+ //
+ MaxBytes = sizeof ( pPort->TxBuffer );
+ DataBytes = MaxBytes - pPort->TxBytes;
+ if ( DataBytes > LengthInBytes ) {
+ DataBytes = LengthInBytes;
+ }
+
+ //
+ // Copy the data into the buffer
+ //
+ CopyMem ( &pPort->TxBuffer[ pPort->TxBytes ],
+ pBuffer,
+ DataBytes );
+
+ //
+ // Account for the data copied
+ //
+ pPort->TxBytes += DataBytes;
+ LengthInBytes -= DataBytes;
+
+ //
+ // Transmit the buffer if it is full
+ //
+ if ( MaxBytes <= pPort->TxBytes ) {
+ Status = HttpFlush ( SocketFD, pPort );
+ }
+ } while (( EFI_SUCCESS == Status ) && ( 0 < LengthInBytes ));
+
+ //
+ // Return the operation status
+ //
+ return Status;
+}
+
+
+/**
+ Send an ANSI string
+
+ @param [in] SocketFD The socket's file descriptor to add to the list.
+ @param [in] pPort The WSDT_PORT structure address
+ @param [in] pString A zero terminated Unicode string
+
+ @retval EFI_SUCCESS The request was successfully processed
+
+**/
+EFI_STATUS
+HttpSendAnsiString (
+ IN int SocketFD,
+ IN WSDT_PORT * pPort,
+ IN CONST char * pString
+ )
+{
+ CONST char * pData;
+ EFI_STATUS Status;
+
+ //
+ // Assume success
+ //
+ Status = EFI_SUCCESS;
+
+ //
+ // Walk the characters in he string
+ //
+ pData = pString;
+ while ( 0 != *pData ) {
+ pData += 1;
+ }
+
+ //
+ // Send the string
+ //
+ Status = HttpSend ( SocketFD,
+ pPort,
+ pData - pString,
+ (CONST UINT8 *)pString );
+
+ //
+ // Return the operation status
+ //
+ return Status;
+}
+
+
+/**
+ Buffer a single byte
+
+ @param [in] SocketFD The socket's file descriptor to add to the list.
+ @param [in] pPort The WSDT_PORT structure address
+ @param [in] Data The data byte to send
+
+ @retval EFI_SUCCESS The request was successfully processed
+
+**/
+EFI_STATUS
+HttpSendByte (
+ IN int SocketFD,
+ IN WSDT_PORT * pPort,
+ IN UINT8 Data
+ )
+{
+ EFI_STATUS Status;
+
+ //
+ // Send the data byte
+ //
+ Status = HttpSend ( SocketFD,
+ pPort,
+ 1,
+ &Data );
+
+ //
+ // Return the operation status
+ //
+ return Status;
+}
+
+
+/**
+ Display a character
+
+ @param [in] SocketFD The socket's file descriptor to add to the list.
+ @param [in] pPort The WSDT_PORT structure address
+ @param [in] Character Character to display
+ @param [in] pReplacement Replacement character string
+
+ @retval EFI_SUCCESS The request was successfully processed
+
+**/
+EFI_STATUS
+HttpSendCharacter (
+ IN int SocketFD,
+ IN WSDT_PORT * pPort,
+ IN CHAR8 Character,
+ IN CHAR8 * pReplacement
+ )
+{
+ EFI_STATUS Status;
+
+ //
+ // Determine if this is a printable character
+ //
+ if (( 0x20 <= Character ) && ( 0x7f > Character )) {
+ if ( '<' == Character ) {
+ //
+ // Replace with HTML equivalent
+ //
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ "<" );
+ }
+ else if ( '>' == Character ) {
+ //
+ // Replace with HTML equivalent
+ //
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ ">" );
+ }
+ else if ( '&' == Character ) {
+ //
+ // Replace with HTML equivalent
+ //
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ "&" );
+ }
+ else if ( '\"' == Character ) {
+ //
+ // Replace with HTML equivalent
+ //
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ """ );
+ }
+ else {
+ //
+ // Display the character
+ //
+ Status = HttpSendByte ( SocketFD,
+ pPort,
+ Character );
+ }
+ }
+ else {
+ //
+ // Not a displayable character
+ //
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ pReplacement );
+ }
+
+ //
+ // Return the operation status
+ //
+ return Status;
+}
+
+
+/**
+ Send a buffer dump
+
+ @param [in] SocketFD The socket's file descriptor to add to the list.
+ @param [in] pPort The WSDT_PORT structure address
+ @param [in] ByteCount The number of bytes to display
+ @param [in] pData Address of the byte array
+
+ @retval EFI_SUCCESS The request was successfully processed
+
+**/
+EFI_STATUS
+HttpSendDump (
+ IN int SocketFD,
+ IN WSDT_PORT * pPort,
+ IN UINTN ByteCount,
+ IN CONST UINT8 * pData
+ )
+{
+ INTN BytesToDisplay;
+ UINT8 Character;
+ INTN Index;
+ INTN InitialSpaces;
+ CONST UINT8 * pDataEnd;
+ CONST UINT8 * pEnd;
+ CONST UINT8 * pTemp;
+ EFI_STATUS Status;
+
+ //
+ // Use for/break instead of goto
+ //
+ for ( ; ; ) {
+ //
+ // Start the field value
+ //
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ "<code>" );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Walk the bytes to be displayed
+ //
+ pEnd = &pData[ ByteCount ];
+ while ( pEnd > pData ) {
+ //
+ // Display the address
+ //
+ Status = HttpSendHexBits ( SocketFD,
+ pPort,
+ sizeof ( pData ) * 8,
+ (UINT64)(UINTN)pData );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Separate the address and data
+ //
+ Status = HttpSendByte ( SocketFD, pPort, ':' );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Position the starting data correctly
+ //
+ InitialSpaces = (UINTN)pData;
+ InitialSpaces &= BYTES_ON_A_LINE - 1;
+ for ( Index = SPACES_ADDRESS_TO_DATA
+ + (( 2 + SPACES_BETWEEN_BYTES )
+ * InitialSpaces );
+ 0 < Index; Index-- ) {
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ " " );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ }
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Display the data
+ //
+ BytesToDisplay = pEnd - pData;
+ if (( BYTES_ON_A_LINE - InitialSpaces ) < BytesToDisplay ) {
+ BytesToDisplay = BYTES_ON_A_LINE - InitialSpaces;
+ }
+ pDataEnd = &pData[ BytesToDisplay ];
+ pTemp = pData;
+ while ( pDataEnd > pTemp ) {
+ Status = HttpSendHexBits ( SocketFD,
+ pPort,
+ 8,
+ *pTemp++ );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Separate the data bytes
+ //
+ for ( Index = SPACES_BETWEEN_BYTES; 0 < Index; Index-- ) {
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ " " );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ }
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ }
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Separate the data from the ASCII display
+ //
+ for ( Index = (( 2 + SPACES_BETWEEN_BYTES )
+ * ( BYTES_ON_A_LINE - BytesToDisplay - InitialSpaces ))
+ - SPACES_BETWEEN_BYTES
+ + SPACES_DATA_TO_ASCII
+ + InitialSpaces;
+ 0 < Index; Index-- ) {
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ " " );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ }
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Display the ASCII data
+ //
+ while ( pDataEnd > pData ) {
+ Character = *pData++;
+ Status = HttpSendCharacter ( SocketFD,
+ pPort,
+ Character,
+ "." );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ }
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Terminate the line
+ //
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ "<br/>\r\n" );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ }
+
+ //
+ // Terminate the field value and row
+ //
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ "</code>\r\n" );
+ break;
+ }
+
+ //
+ // Return the operation status
+ //
+ return Status;
+}
+
+
+/**
+ Display a row containing a GUID value
+
+ @param [in] SocketFD The socket's file descriptor to add to the list.
+ @param [in] pPort The WSDT_PORT structure address
+ @param [in] pGuid Address of the GUID to display
+
+ @retval EFI_SUCCESS The request was successfully processed
+
+**/
+EFI_STATUS
+HttpSendGuid (
+ IN int SocketFD,
+ IN WSDT_PORT * pPort,
+ IN CONST EFI_GUID * pGuid
+ )
+{
+ UINT32 Index;
+ EFI_STATUS Status;
+
+ DBG_ENTER ( );
+
+ //
+ // Use for/break instead of goto
+ //
+ for ( ; ; ) {
+ //
+ // Display the GUID in a form found in the code
+ //
+ // E.g. 0xca16005f, 0x11ec, 0x4bdc, { 0x99, 0x97, 0x27, 0x2c, 0xa9, 0xba, 0x15, 0xe5 }
+ //
+
+ //
+ // Display the first 32 bits
+ //
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ "0x" );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = HttpSendHexBits ( SocketFD,
+ pPort,
+ 32,
+ pGuid->Data1 );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Display the second 16 bits
+ //
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ ", 0x" );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = HttpSendHexBits ( SocketFD,
+ pPort,
+ 16,
+ pGuid->Data2 );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Display the thrid 16 bits
+ //
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ ", 0x" );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = HttpSendHexBits ( SocketFD,
+ pPort,
+ 16,
+ pGuid->Data3 );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Place the last 64 bits in braces
+ //
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ ", { 0x" );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ for ( Index = 0; 7 >= Index; Index++ ) {
+ //
+ // Display the next 8 bits
+ //
+ Status = HttpSendHexBits ( SocketFD,
+ pPort,
+ 8,
+ pGuid->Data4[ Index ]);
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Separate the bytes
+ //
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ ( 7 != Index ) ? ", 0x" : " }" );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ }
+ break;
+ }
+
+ //
+ // Return the operation status
+ //
+ DBG_EXIT_STATUS ( Status );
+ return Status;
+}
+
+
+/**
+ Output a hex value to the HTML page
+
+ @param [in] SocketFD Socket file descriptor
+ @param [in] pPort The WSDT_PORT structure address
+ @param [in] Bits Number of bits to display
+ @param [in] Value Value to display
+
+ @retval EFI_SUCCESS Successfully displayed the address
+**/
+EFI_STATUS
+HttpSendHexBits (
+ IN int SocketFD,
+ IN WSDT_PORT * pPort,
+ IN INT32 Bits,
+ IN UINT64 Value
+ )
+{
+ UINT32 Digit;
+ INT32 Shift;
+ EFI_STATUS Status;
+
+ //
+ // Assume success
+ //
+ Status = EFI_SUCCESS;
+
+ //
+ // Walk the list of divisors
+ //
+ Shift = (( Bits + 3 ) & ( ~3 )) - 4;
+ while ( 0 <= Shift ) {
+ //
+ // Determine the next digit
+ //
+ Digit = (UINT32)(( Value >> Shift ) & 0xf );
+ if ( 10 <= Digit ) {
+ Digit += 'a' - '0' - 10;
+ }
+
+ //
+ // Display the digit
+ //
+ Status = HttpSendByte ( SocketFD, pPort, (UINT8)( '0' + Digit ));
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Set the next shift
+ //
+ Shift -= 4;
+ }
+
+ //
+ // Return the operation status
+ //
+ return Status;
+}
+
+
+/**
+ Output a hex 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
+
+ @retval EFI_SUCCESS Successfully displayed the address
+**/
+EFI_STATUS
+HttpSendHexValue (
+ IN int SocketFD,
+ IN WSDT_PORT * pPort,
+ IN UINT64 Value
+ )
+{
+ BOOLEAN bDisplayZeros;
+ UINT32 Digit;
+ INT32 Shift;
+ EFI_STATUS Status;
+
+ //
+ // Assume success
+ //
+ Status = EFI_SUCCESS;
+
+ //
+ // Walk the list of divisors
+ //
+ bDisplayZeros = FALSE;
+ Shift = 60;
+ do {
+ //
+ // Determine the next digit
+ //
+ Digit = (UINT32)(( Value >> Shift ) & 0xf );
+ if ( 10 <= Digit ) {
+ Digit += 'a' - '0' - 10;
+ }
+
+ //
+ // Suppress leading zeros
+ //
+ if (( 0 != Digit ) || bDisplayZeros || ( 0 == Shift )) {
+ bDisplayZeros = TRUE;
+
+ //
+ // Display the digit
+ //
+ Status = HttpSendByte ( SocketFD, pPort, (UINT8)( '0' + Digit ));
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ }
+
+ //
+ // Set the next shift
+ //
+ Shift -= 4;
+ } while ( 0 <= Shift );
+
+ //
+ // Return the operation status
+ //
+ return Status;
+}
+
+
+/**
+ 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
+
+ @param [in] SocketFD Socket file descriptor
+ @param [in] pPort The WSDT_PORT structure address
+ @param [in] pAddress Address of the socket address
+
+ @retval EFI_SUCCESS Successfully displayed the address
+**/
+EFI_STATUS
+HttpSendIpAddress (
+ IN int SocketFD,
+ IN WSDT_PORT * pPort,
+ IN struct sockaddr_in6 * pAddress
+ )
+{
+ BOOLEAN bZeroSuppression;
+ UINT32 Index;
+ struct sockaddr_in * pIpv4;
+ struct sockaddr_in6 * pIpv6;
+ UINT16 PortNumber;
+ EFI_STATUS Status;
+
+ //
+ // Use break instead of goto
+ //
+ 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;
+ }
+
+ //
+ // Return the operation status
+ //
+ return Status;
+}
+
+
+/**
+ Send a Unicode string
+
+ @param [in] SocketFD The socket's file descriptor to add to the list.
+ @param [in] pPort The WSDT_PORT structure address
+ @param [in] pString A zero terminated Unicode string
+
+ @retval EFI_SUCCESS The request was successfully processed
+
+**/
+EFI_STATUS
+HttpSendUnicodeString (
+ IN int SocketFD,
+ IN WSDT_PORT * pPort,
+ IN CONST UINT16 * pString
+ )
+{
+ UINT8 Data;
+ UINT16 Character;
+ EFI_STATUS Status;
+
+ //
+ // Assume success
+ //
+ Status = EFI_SUCCESS;
+
+ //
+ // Walk the characters in he string
+ //
+ while ( 0 != ( Character = *pString++ )) {
+ //
+ // Convert the character to UTF-8
+ //
+ if ( 0 != ( Character & 0xf800 )) {
+ //
+ // Send the upper 4 bits
+ //
+ Data = (UINT8)(( Character >> 12 ) & 0xf );
+ Data |= 0xe0;
+ Status = HttpSendByte ( SocketFD,
+ pPort,
+ Data );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Send the next 6 bits
+ //
+ Data = (UINT8)(( Character >> 6 ) & 0x3f );
+ Data |= 0x80;
+ Status = HttpSendByte ( SocketFD,
+ pPort,
+ Data );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Send the last 6 bits
+ //
+ Data = (UINT8)( Character & 0x3f );
+ Data |= 0x80;
+ }
+ else if ( 0 != ( Character & 0x0780 )) {
+ //
+ // Send the upper 5 bits
+ //
+ Data = (UINT8)(( Character >> 6 ) & 0x1f );
+ Data |= 0xc0;
+ Status = HttpSendByte ( SocketFD,
+ pPort,
+ Data );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Send the last 6 bits
+ //
+ Data = (UINT8)( Character & 0x3f );
+ Data |= 0x80;
+ }
+ else {
+ Data = (UINT8)( Character & 0x7f );
+ }
+
+ //
+ // Send the last data byte
+ //
+ Status = HttpSendByte ( SocketFD,
+ pPort,
+ Data );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ }
+
+ //
+ // Return the operation status
+ //
+ return Status;
+}
+
+
+/**
+ Output a 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
+
+ @retval EFI_SUCCESS Successfully displayed the address
+**/
+EFI_STATUS
+HttpSendValue (
+ IN int SocketFD,
+ IN WSDT_PORT * pPort,
+ IN UINT64 Value
+ )
+{
+ BOOLEAN bDisplayZeros;
+ UINT64 Digit;
+ CONST UINT64 * pEnd;
+ CONST UINT64 * pDivisor;
+ CONST UINT64 pDivisors[ ] = {
+ 10000000000000000000ULL,
+ 1000000000000000000ULL,
+ 100000000000000000ULL,
+ 10000000000000000ULL,
+ 1000000000000000ULL,
+ 100000000000000ULL,
+ 10000000000000ULL,
+ 1000000000000ULL,
+ 100000000000ULL,
+ 10000000000ULL,
+ 1000000000ULL,
+ 100000000ULL,
+ 10000000ULL,
+ 1000000ULL,
+ 100000ULL,
+ 10000ULL,
+ 1000ULL,
+ 100ULL,
+ 10ULL
+ };
+ EFI_STATUS Status;
+ UINT64 Temp;
+
+ //
+ // Assume success
+ //
+ Status = EFI_SUCCESS;
+
+ //
+ // Walk the list of divisors
+ //
+ bDisplayZeros = FALSE;
+ pDivisor = &pDivisors[0];
+ pEnd = &pDivisor[ sizeof ( pDivisors ) / sizeof ( pDivisors[0])];
+ while ( pEnd > pDivisor ) {
+ //
+ // Determine the next digit
+ //
+ Digit = Value / *pDivisor;
+
+ //
+ // Suppress leading zeros
+ //
+ if (( 0 != Digit ) || bDisplayZeros ) {
+ bDisplayZeros = TRUE;
+
+ //
+ // Display the digit
+ //
+ Status = HttpSendByte ( SocketFD, pPort, (UINT8)( '0' + Digit ));
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Determine the remainder
+ //
+ Temp = *pDivisor * Digit;
+ Value -= Temp;
+ }
+
+ //
+ // Set the next divisor
+ //
+ pDivisor += 1;
+ }
+
+ //
+ // Display the final digit
+ //
+ if ( !EFI_ERROR ( Status )) {
+ Status = HttpSendByte ( SocketFD, pPort, (UINT8)( '0' + Value ));
+ }
+
+ //
+ // Return the operation status
+ //
+ return Status;
+}
diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/WebServer/Handles.c b/uefi/linaro-edk2/AppPkg/Applications/Sockets/WebServer/Handles.c
new file mode 100644
index 0000000..19a55dd
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/WebServer/Handles.c
@@ -0,0 +1,284 @@
+/**
+ @file
+ Display the handles in the system
+
+ Copyright (c) 2011-2012, Intel Corporation
+ All rights reserved. This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <WebServer.h>
+
+
+/**
+ Respond with the handles in the system
+
+ @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
+HandlePage (
+ IN int SocketFD,
+ IN WSDT_PORT * pPort,
+ OUT BOOLEAN * pbDone
+ )
+{
+ INTN Digit;
+ INTN Entries;
+ INTN Index;
+ UINTN GuidCount;
+ UINTN LengthInBytes;
+ UINT8 * pDigit;
+ EFI_HANDLE * pHandleArray;
+ EFI_HANDLE * pHandle;
+ EFI_HANDLE * pHandleEnd;
+ EFI_GUID ** ppGuidArray;
+ EFI_GUID ** ppGuid;
+ EFI_GUID ** ppGuidEnd;
+ INTN Shift;
+ EFI_STATUS Status;
+ UINTN Value;
+ CONST UINTN cDigit [] = {
+ 3, 2, 1, 0, 5, 4, 7, 6, 8, 9, 10, 11, 12, 13, 14, 15 };
+
+ DBG_ENTER ( );
+
+ //
+ // Send the handles page
+ //
+ for ( ; ; ) {
+ //
+ // Send the page header
+ //
+ Status = HttpPageHeader ( SocketFD, pPort, L"Handle Database" );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Build the table header
+ //
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ "<h1>Handle Database</h1>\r\n"
+ "<table border=\"1\">\r\n"
+ " <tr bgcolor=\"c0c0ff\"><th>Handle</th><th>Protocol Guids</th></tr>\r\n" );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Determine the number of handles in the database
+ //
+ LengthInBytes = 0;
+ Status = gBS->LocateHandle ( AllHandles,
+ NULL,
+ NULL,
+ &LengthInBytes,
+ NULL );
+ if ( EFI_BUFFER_TOO_SMALL == Status ) {
+ //
+ // Allocate space for the handles
+ //
+ Status = gBS->AllocatePool ( EfiRuntimeServicesData,
+ LengthInBytes,
+ (VOID **) &pHandleArray );
+ if ( !EFI_ERROR ( Status )) {
+ //
+ // Get the list of handles
+ //
+ Status = gBS->LocateHandle ( AllHandles,
+ NULL,
+ NULL,
+ &LengthInBytes,
+ pHandleArray );
+ if ( !EFI_ERROR ( Status )) {
+ Entries = LengthInBytes / sizeof ( *pHandleArray );
+ pHandle = pHandleArray;
+ pHandleEnd = &pHandle [ Entries ];
+ while ( pHandleEnd > pHandle ) {
+ //
+ // Build the table entry for this page
+ //
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ "<tr><td><code>0x" );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Value = (UINTN) *pHandle;
+ for ( Shift = ( sizeof ( Shift ) << 3 ) - 4; 0 <= Shift; Shift -= 4 ) {
+ //
+ // Convert the next address nibble to ANSI hex
+ //
+ Digit = (( Value >> Shift ) & 0xf ) | '0';
+ if ( '9' < Digit ) {
+ Digit += 'a' - '0' - 10;
+ }
+
+ //
+ // Display the address digit
+ //
+ Status = HttpSendByte ( SocketFD,
+ pPort,
+ (UINT8) Digit );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ }
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Start the second column
+ //
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ "</code></td><td><code>\r\n" );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Determine the number of protocols connected to this handle
+ //
+ Status = gBS->ProtocolsPerHandle ( *pHandle,
+ &ppGuidArray,
+ &GuidCount );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ ppGuid = ppGuidArray;
+ ppGuidEnd = &ppGuid [ GuidCount ];
+ while ( ppGuidEnd > ppGuid ) {
+ //
+ // Display the guid
+ //
+ pDigit = (UINT8 *) *ppGuid;
+ for ( Index = 0; 16 > Index; Index++ ) {
+ //
+ // Separate the portions of the GUID
+ // 99E87DCF-6162-40c5-9FA1-32111F5197F7
+ //
+ if (( 4 == Index )
+ || ( 6 == Index )
+ || ( 8 == Index )
+ || ( 10 == Index )) {
+ Status = HttpSendByte ( SocketFD,
+ pPort,
+ '-' );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ }
+
+ //
+ // Display the GUID digits
+ //
+ Value = pDigit [ cDigit [ Index ]];
+ for ( Shift = 4; 0 <= Shift; Shift -= 4 ) {
+ //
+ // Convert the next address nibble to ANSI hex
+ //
+ Digit = (( Value >> Shift ) & 0xf ) | '0';
+ if ( '9' < Digit ) {
+ Digit += 'a' - '0' - 10;
+ }
+
+ //
+ // Display the address digit
+ //
+ Status = HttpSendByte ( SocketFD,
+ pPort,
+ (UINT8) Digit );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ }
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ }
+
+ //
+ // Separate each GUID
+ //
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ "<br/>\r\n" );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Set the next protocol
+ //
+ ppGuid+= 1;
+ }
+
+ //
+ // Free the GUID array
+ //
+ gBS->FreePool ( ppGuidArray );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // End the row
+ //
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ "</code></td></tr>\r\n" );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Set the next handle
+ //
+ pHandle += 1;
+ }
+ }
+
+ //
+ // Done with the handle array
+ //
+ gBS->FreePool ( pHandleArray );
+ }
+ }
+
+ //
+ // Build the table trailer
+ //
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ "</table>\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/uefi/linaro-edk2/AppPkg/Applications/Sockets/WebServer/Hello.c b/uefi/linaro-edk2/AppPkg/Applications/Sockets/WebServer/Hello.c
new file mode 100644
index 0000000..3d1f979
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/WebServer/Hello.c
@@ -0,0 +1,77 @@
+/**
+ @file
+ Hello World response page
+
+ Copyright (c) 2011-2012, Intel Corporation
+ All rights reserved. This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <WebServer.h>
+
+
+/**
+ Respond with the Hello World 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
+HelloPage (
+ IN int SocketFD,
+ IN WSDT_PORT * pPort,
+ OUT BOOLEAN * pbDone
+ )
+{
+ EFI_STATUS Status;
+
+ DBG_ENTER ( );
+
+ //
+ // Send the Hello World page
+ //
+ for ( ; ; ) {
+ //
+ // Send the page header
+ //
+ Status = HttpPageHeader ( SocketFD, pPort, L"Hello World" );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Send the page body
+ //
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ "<h1>Hello World</h1>\r\n"
+ "<p>\r\n"
+ " This response was generated by the UEFI 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;
+}
diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/WebServer/Index.c b/uefi/linaro-edk2/AppPkg/Applications/Sockets/WebServer/Index.c
new file mode 100644
index 0000000..64c1ffc
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/WebServer/Index.c
@@ -0,0 +1,151 @@
+/**
+ @file
+ Generate the list of known pages.
+
+ Copyright (c) 2011-2012, Intel Corporation
+ All rights reserved. This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <WebServer.h>
+
+
+/**
+ Respond with the list of known pages
+
+ @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
+IndexPage (
+ IN int SocketFD,
+ IN WSDT_PORT * pPort,
+ OUT BOOLEAN * pbDone
+ )
+{
+ CONST DT_PAGE * pPage;
+ CONST DT_PAGE * pPageEnd;
+ EFI_STATUS Status;
+
+ DBG_ENTER ( );
+
+ //
+ // Send the index page
+ //
+ for ( ; ; ) {
+ //
+ // Send the page header
+ //
+ Status = HttpPageHeader ( SocketFD, pPort, L"Index" );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Build the table header
+ //
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ "<h1>UEFI Web Server</h1>\r\n"
+ "<table border=\"1\">\r\n"
+ " <tr bgcolor=\"c0c0ff\"><th>Page</th><th>Description</th></tr>\r\n" );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Walk the list of pages
+ // Skip the first page
+ //
+ pPage = &mPageList[0];
+ pPageEnd = &pPage[mPageCount];
+ pPage += 1;
+ while ( pPageEnd > pPage ) {
+ //
+ // Build the table entry for this page
+ //
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ "<tr><td><a target=\"_blank\" href=\"" );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = HttpSendUnicodeString ( SocketFD,
+ pPort,
+ &pPage->pPageName[1]);
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ "\">" );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = HttpSendUnicodeString ( SocketFD,
+ pPort,
+ &pPage->pPageName[1]);
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ "</a></td><td>" );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = HttpSendUnicodeString ( SocketFD,
+ pPort,
+ pPage->pDescription );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ "</td></tr>\r\n" );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Set the next page
+ //
+ pPage += 1;
+ }
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Build the table trailer
+ //
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ "</table>\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/uefi/linaro-edk2/AppPkg/Applications/Sockets/WebServer/MemoryMap.c b/uefi/linaro-edk2/AppPkg/Applications/Sockets/WebServer/MemoryMap.c
new file mode 100644
index 0000000..71a5b1d
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/WebServer/MemoryMap.c
@@ -0,0 +1,364 @@
+/**
+ @file
+ Display the memory map
+
+ Copyright (c) 2012, Intel Corporation
+ All rights reserved. This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <WebServer.h>
+#include <PiDxe.h>
+#include <Library/DxeServicesTableLib.h>
+
+
+CONST char * mpMemoryType[ ] = {
+ "Non-existent",
+ "Reserved",
+ "System Memory",
+ "Memory Mapped I/O"
+};
+
+
+/**
+ Page to display the memory map
+
+ @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
+MemoryMapPage (
+ IN int SocketFD,
+ IN WSDT_PORT * pPort,
+ OUT BOOLEAN * pbDone
+ )
+{
+ UINT64 Attributes;
+ BOOLEAN bSomethingDisplayed;
+ UINTN Count;
+ EFI_GCD_MEMORY_SPACE_DESCRIPTOR * pMemoryEnd;
+ EFI_GCD_MEMORY_SPACE_DESCRIPTOR * pMemoryDescriptor;
+ EFI_GCD_MEMORY_SPACE_DESCRIPTOR * pMemoryDescriptorStart;
+ EFI_STATUS Status;
+
+ DBG_ENTER ( );
+
+ //
+ // Send the memory map page
+ //
+ pMemoryDescriptorStart = NULL;
+ for ( ; ; ) {
+ //
+ // Send the page header
+ //
+ Status = HttpPageHeader ( SocketFD, pPort, L"Memory Map" );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Start the table
+ //
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ "<h1>Memory Map</h1>\r\n"
+ "<table>\r\n"
+ " <tr><th align=\"right\">Type</th><th align=\"right\">Start</th><th align=\"right\">End</th><th align=\"right\">Attributes</th></tr>\r\n" );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Get the memory map
+ //
+ Status = gDS->GetMemorySpaceMap ( &Count,
+ &pMemoryDescriptor );
+ if ( !EFI_ERROR ( Status )) {
+ pMemoryDescriptorStart = pMemoryDescriptor;
+ pMemoryEnd = &pMemoryDescriptor[ Count ];
+ while ( pMemoryEnd > pMemoryDescriptor ) {
+ //
+ // Display the type
+ //
+ Status = HttpSendAnsiString ( SocketFD, pPort, "<tr><td align=\"right\"><code>" );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ if ( DIM ( mpMemoryType ) > pMemoryDescriptor->GcdMemoryType ) {
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ mpMemoryType[ pMemoryDescriptor->GcdMemoryType ]);
+ }
+ else {
+ Status = HttpSendValue ( SocketFD,
+ pPort,
+ pMemoryDescriptor->GcdMemoryType );
+ }
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Display the start address
+ //
+ Status = HttpSendAnsiString ( SocketFD, pPort, "</code></td><td align=\"right\"><code>0x" );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = HttpSendHexValue ( SocketFD,
+ pPort,
+ pMemoryDescriptor->BaseAddress );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Display the end address
+ //
+ Status = HttpSendAnsiString ( SocketFD, pPort, "</code></td><td align=\"right\"><code>0x" );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = HttpSendHexValue ( SocketFD,
+ pPort,
+ pMemoryDescriptor->BaseAddress
+ + pMemoryDescriptor->Length
+ - 1 );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Display the attributes
+ //
+ Status = HttpSendAnsiString ( SocketFD, pPort, "</code></td><td align=\"right\"><code>0x" );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = HttpSendHexValue ( SocketFD,
+ pPort,
+ pMemoryDescriptor->Attributes );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Decode the attributes
+ //
+ Status = HttpSendAnsiString ( SocketFD, pPort, "</code></td><td>" );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ bSomethingDisplayed = FALSE;
+ Attributes = pMemoryDescriptor->Attributes;
+
+ if ( 0 != ( Attributes & EFI_MEMORY_RUNTIME )) {
+ bSomethingDisplayed = TRUE;
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ "Runtime" );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ }
+
+ if ( 0 != ( Attributes & EFI_MEMORY_XP )) {
+ if ( bSomethingDisplayed ) {
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ ", " );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ }
+ bSomethingDisplayed = TRUE;
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ "No Execute" );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ }
+
+ if ( 0 != ( Attributes & EFI_MEMORY_RP )) {
+ if ( bSomethingDisplayed ) {
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ ", " );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ }
+ bSomethingDisplayed = TRUE;
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ "No Read" );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ }
+
+ if ( 0 != ( Attributes & EFI_MEMORY_WP )) {
+ if ( bSomethingDisplayed ) {
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ ", " );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ }
+ bSomethingDisplayed = TRUE;
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ "No Write" );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ }
+
+ if ( 0 != ( Attributes & EFI_MEMORY_UCE )) {
+ if ( bSomethingDisplayed ) {
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ ", " );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ }
+ bSomethingDisplayed = TRUE;
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ "UCE" );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ }
+
+
+ if ( 0 != ( Attributes & EFI_MEMORY_WB )) {
+ if ( bSomethingDisplayed ) {
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ ", " );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ }
+ bSomethingDisplayed = TRUE;
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ "Write Back" );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ }
+
+ if ( 0 != ( Attributes & EFI_MEMORY_WT )) {
+ if ( bSomethingDisplayed ) {
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ ", " );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ }
+ bSomethingDisplayed = TRUE;
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ "Write Through" );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ }
+
+ if ( 0 != ( Attributes & EFI_MEMORY_WC )) {
+ if ( bSomethingDisplayed ) {
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ ", " );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ }
+ bSomethingDisplayed = TRUE;
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ "Write Combining" );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ }
+
+ if ( 0 != ( Attributes & EFI_MEMORY_UC )) {
+ if ( bSomethingDisplayed ) {
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ ", " );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ }
+ bSomethingDisplayed = TRUE;
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ "Uncached" );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ }
+
+ //
+ // Finish the row
+ //
+ Status = HttpSendAnsiString ( SocketFD, pPort, "</td></tr>" );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Set the next memory descriptor
+ //
+ pMemoryDescriptor += 1;
+ }
+ }
+
+ //
+ // Finish the table
+ //
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ "</table>\r\n" );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Send the page trailer
+ //
+ Status = HttpPageTrailer ( SocketFD, pPort, pbDone );
+ break;
+ }
+
+ //
+ // Release the memory descriptors
+ //
+ if ( NULL != pMemoryDescriptorStart ) {
+ FreePool ( pMemoryDescriptorStart );
+ }
+
+ //
+ // Return the operation status
+ //
+ DBG_EXIT_STATUS ( Status );
+ return Status;
+}
diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/WebServer/Mtrr.c b/uefi/linaro-edk2/AppPkg/Applications/Sockets/WebServer/Mtrr.c
new file mode 100644
index 0000000..92f90b0
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/WebServer/Mtrr.c
@@ -0,0 +1,825 @@
+/**
+ @file
+ Display the memory type range registers
+
+ Copyright (c) 2012, Intel Corporation
+ All rights reserved. This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <WebServer.h>
+#include <Library/MtrrLib.h>
+
+#define VARIABLE_MTRR_VALID 0x800
+
+CONST char * mMemoryType [ ] = {
+ "Uncached",
+ "Write Combining",
+ "Reserved",
+ "Reserved",
+ "Write Through",
+ "Write Protected",
+ "Writeback"
+};
+
+
+/**
+ Display a fixed MTRR row
+
+ @param [in] SocketFD The socket's file descriptor to add to the list.
+ @param [in] pPort The WSDT_PORT structure address
+ @param [in] Start Start address for the region
+ @param [in] End End address for the region
+ @param [in] Type Memory type
+
+ @retval EFI_SUCCESS The request was successfully processed
+
+**/
+EFI_STATUS
+MtrrDisplayFixedRow (
+ IN int SocketFD,
+ IN WSDT_PORT * pPort,
+ IN UINT64 Start,
+ IN UINT64 End,
+ IN UINT64 Type
+ )
+{
+ EFI_STATUS Status;
+
+ //
+ // Use break instead of goto
+ //
+ for ( ; ; ) {
+ //
+ // Start the row
+ //
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ " <tr><td align=\"right\"><code>0x" );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Start
+ //
+ Status = HttpSendHexValue ( SocketFD,
+ pPort,
+ Start );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // End
+ //
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ "</code></td><td align=\"right\"><code>0x" );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = HttpSendHexValue ( SocketFD,
+ pPort,
+ End - 1 );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Type
+ //
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ "</code></td><td>" );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Type &= 0xff;
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ ( DIM ( mMemoryType ) > Type )
+ ? mMemoryType [ Type ]
+ : "Reserved" );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // End of row
+ //
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ "</td></tr>\r\n" );
+ break;
+ }
+
+ //
+ // Return the final status
+ //
+ return Status;
+}
+
+
+/**
+ Display the memory type registers
+
+ @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
+MemoryTypeRegistersPage (
+ IN int SocketFD,
+ IN WSDT_PORT * pPort,
+ OUT BOOLEAN * pbDone
+ )
+{
+ UINT64 Addr;
+ BOOLEAN bValid;
+ UINT64 Capabilities;
+ UINTN Count;
+ UINT64 DefType;
+ UINTN Index;
+ UINT64 Mask;
+ UINT64 MaxMtrrs;
+ CONST UINT64 mFixedAddresses [( 8 * MTRR_NUMBER_OF_FIXED_MTRR ) + 1 ] = {
+ 0ULL,
+ 0x10000ULL,
+ 0x20000ULL,
+ 0x30000ULL,
+ 0x40000ULL,
+ 0x50000ULL,
+ 0x60000ULL,
+ 0x70000ULL,
+
+ 0x80000ULL,
+ 0x84000ULL,
+ 0x88000ULL,
+ 0x8c000ULL,
+ 0x90000ULL,
+ 0x94000ULL,
+ 0x98000ULL,
+ 0x9c000ULL,
+
+ 0xa0000ULL,
+ 0xa4000ULL,
+ 0xa8000ULL,
+ 0xac000ULL,
+ 0xb0000ULL,
+ 0xb4000ULL,
+ 0xb8000ULL,
+ 0xbc000ULL,
+
+ 0xc0000ULL,
+ 0xc1000ULL,
+ 0xc2000ULL,
+ 0xc3000ULL,
+ 0xc4000ULL,
+ 0xc5000ULL,
+ 0xc6000ULL,
+ 0xc7000ULL,
+
+ 0xc8000ULL,
+ 0xc9000ULL,
+ 0xca000ULL,
+ 0xcb000ULL,
+ 0xcc000ULL,
+ 0xcd000ULL,
+ 0xce000ULL,
+ 0xcf000ULL,
+
+ 0xd0000ULL,
+ 0xd1000ULL,
+ 0xd2000ULL,
+ 0xd3000ULL,
+ 0xd4000ULL,
+ 0xd5000ULL,
+ 0xd6000ULL,
+ 0xd7000ULL,
+
+ 0xd8000ULL,
+ 0xd9000ULL,
+ 0xda000ULL,
+ 0xdb000ULL,
+ 0xdc000ULL,
+ 0xdd000ULL,
+ 0xde000ULL,
+ 0xdf000ULL,
+
+ 0xe0000ULL,
+ 0xe1000ULL,
+ 0xe2000ULL,
+ 0xe3000ULL,
+ 0xe4000ULL,
+ 0xe5000ULL,
+ 0xe6000ULL,
+ 0xe7000ULL,
+
+ 0xe8000ULL,
+ 0xe9000ULL,
+ 0xea000ULL,
+ 0xeb000ULL,
+ 0xec000ULL,
+ 0xed000ULL,
+ 0xee000ULL,
+ 0xef000ULL,
+
+ 0xf0000ULL,
+ 0xf1000ULL,
+ 0xf2000ULL,
+ 0xf3000ULL,
+ 0xf4000ULL,
+ 0xf5000ULL,
+ 0xf6000ULL,
+ 0xf7000ULL,
+
+ 0xf8000ULL,
+ 0xf9000ULL,
+ 0xfa000ULL,
+ 0xfb000ULL,
+ 0xfc000ULL,
+ 0xfd000ULL,
+ 0xfe000ULL,
+ 0xff000ULL,
+
+ 0x100000ULL
+ };
+ MTRR_SETTINGS Mtrr;
+ CONST UINT64 * pMemEnd;
+ CONST UINT64 * pMemStart;
+ UINT64 PreviousType;
+ UINT64 ShiftCount;
+ EFI_STATUS Status;
+ UINT64 Type;
+ INT64 Value;
+
+ DBG_ENTER ( );
+
+ //
+ // Send the Memory Type Registers page
+ //
+ for ( ; ; ) {
+ //
+ // Send the page header
+ //
+ Status = HttpPageHeader ( SocketFD, pPort, L"Memory Type Range Registers" );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Send the header
+ //
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ "<h1>Memory Type Range Registers</h1>\r\n" );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Determine if MTRRs are supported
+ //
+ if ( !IsMtrrSupported ( )) {
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ "<p>Memory Type Range Registers are not supported!\r\n" );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ }
+ else {
+ //
+ // Get the capabilities
+ //
+ Capabilities = AsmReadMsr64 ( MTRR_LIB_IA32_MTRR_CAP );
+ DefType = AsmReadMsr64 ( MTRR_LIB_IA32_MTRR_DEF_TYPE );
+
+ //
+ // Display the capabilities
+ //
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ "<p>Capabilities: " );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = HttpSendHexValue ( SocketFD,
+ pPort,
+ Capabilities );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ "<br>\r\n" );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Display the default type
+ //
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ "Def Type: " );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = HttpSendHexValue ( SocketFD,
+ pPort,
+ DefType );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ ", MTRRs " );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ ( 0 != ( DefType & MTRR_LIB_CACHE_MTRR_ENABLED ))
+ ? "Enabled"
+ : "Disabled" );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ ", Fixed MTRRs " );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ ( 0 != ( DefType & MTRR_LIB_CACHE_FIXED_MTRR_ENABLED ))
+ ? "Enabled"
+ : "Disabled" );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ ", " );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Type = DefType & 0xff;
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ ( DIM ( mMemoryType ) > Type )
+ ? mMemoryType [ Type ]
+ : "Reserved" );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ "</p>\r\n" );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Determine if MTRRs are enabled
+ //
+ if ( 0 == ( DefType & MTRR_LIB_CACHE_MTRR_ENABLED )) {
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ "<p>All memory is uncached!</p>\r\n" );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ }
+ else {
+ //
+ // Get the MTRRs
+ //
+ MtrrGetAllMtrrs ( &Mtrr );
+
+ //
+ // Determine if the fixed MTRRs are supported
+ //
+ if (( 0 != ( Capabilities & 0x100 ))
+ && ( 0 != ( DefType & MTRR_LIB_CACHE_FIXED_MTRR_ENABLED ))) {
+
+ //
+ // Beginning of table
+ //
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ "<h2>Fixed MTRRs</h2>\r\n"
+ "<table>\r\n"
+ " <tr><th>Index</th><th align=\"right\">Value</th><th align=\"right\">Start</th><th align=\"right\">End</th></tr>\r\n" );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Display the fixed MTRRs
+ //
+ pMemStart = &mFixedAddresses[ 0 ];
+ for ( Count = 0; DIM ( Mtrr.Fixed.Mtrr ) > Count; Count++ ) {
+ //
+ // Start the row
+ //
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ " <tr><td>" );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Index
+ //
+ Status = HttpSendValue ( SocketFD,
+ pPort,
+ Count );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Value
+ //
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ "</td><td align=\"right\"><code>0x" );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = HttpSendHexValue ( SocketFD,
+ pPort,
+ Mtrr.Fixed.Mtrr[ Count ]);
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Start
+ //
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ "</code></td><td align=\"right\"><code>0x" );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = HttpSendHexValue ( SocketFD,
+ pPort,
+ *pMemStart );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ pMemStart += 8;
+
+ //
+ // Value
+ //
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ "</code></td><td align=\"right\"><code>0x" );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = HttpSendHexValue ( SocketFD,
+ pPort,
+ *pMemStart - 1 );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // End of row
+ //
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ "</code></td></tr>\r\n" );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ }
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // End of table
+ //
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ "</table>\r\n" );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Beginning of table
+ //
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ "<table>\r\n"
+ " <tr><th align=\"right\">Start</th><th align=\"right\">End</th><th align=\"left\">Type</th></tr>\r\n" );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Decode the fixed MTRRs
+ //
+ PreviousType = Mtrr.Fixed.Mtrr[ 0 ] & 0xff;
+ pMemStart = &mFixedAddresses[ 0 ];
+ pMemEnd = pMemStart;
+ for ( Count = 0; DIM ( Mtrr.Fixed.Mtrr ) > Count; Count++ ) {
+ //
+ // Get the memory types
+ //
+ Type = Mtrr.Fixed.Mtrr[ Count ];
+
+ //
+ // Walk the memory range
+ //
+ for ( Index = 0; 8 > Index; Index++ ) {
+ //
+ // Determine if this is the same memory type
+ //
+ if ( PreviousType != ( Type & 0xff )) {
+ //
+ // Display the row
+ //
+ Status = MtrrDisplayFixedRow ( SocketFD,
+ pPort,
+ *pMemStart,
+ *pMemEnd,
+ PreviousType );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Start the next range of addresses
+ //
+ pMemStart = pMemEnd;
+ PreviousType = Type & 0xff;
+ }
+
+ //
+ // Set the next memory range and type
+ //
+ Type >>= 8;
+ pMemEnd += 1;
+ }
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ }
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Display the final row
+ //
+ Status = MtrrDisplayFixedRow ( SocketFD,
+ pPort,
+ *pMemStart,
+ *pMemEnd,
+ PreviousType );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // End of table
+ //
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ "</table>\r\n" );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ }
+
+ //
+ // Determine if the variable MTRRs are supported
+ //
+ MaxMtrrs = Capabilities & MTRR_LIB_IA32_MTRR_CAP_VCNT_MASK;
+ if ( 0 < MaxMtrrs ) {
+ //
+ // Beginning of table
+ //
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ "<h2>Variable MTRRs</h2>\r\n"
+ "<table>\r\n"
+ " <tr><th>Index</th><th align=\"right\">Base</th><th align=\"right\">Mask</th><th align=\"right\">Start</th><th align=\"right\">End</th></tr>\r\n" );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Display the variable MTRRs
+ //
+ for ( Count = 0; MaxMtrrs > Count; Count++ ) {
+ //
+ // Start the row
+ //
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ " <tr><td>" );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Index
+ //
+ Status = HttpSendValue ( SocketFD,
+ pPort,
+ Count );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Base
+ //
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ "</td><td align=\"right\"><code>0x" );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = HttpSendHexValue ( SocketFD,
+ pPort,
+ Mtrr.Variables.Mtrr[ Count ].Base );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Mask
+ //
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ "</td><td align=\"right\"><code>0x" );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = HttpSendHexValue ( SocketFD,
+ pPort,
+ Mtrr.Variables.Mtrr[ Count ].Mask );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Determine if the entry is valid
+ //
+ bValid = ( Mtrr.Variables.Mtrr[ Count ].Mask & VARIABLE_MTRR_VALID ) ? TRUE : FALSE;
+
+ //
+ // Start
+ //
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ "</code></td><td align=\"right\"><code>" );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Addr = Mtrr.Variables.Mtrr[ Count ].Base & 0xfffffffffffff000ULL;
+ if ( bValid ) {
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ "0x" );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = HttpSendHexValue ( SocketFD,
+ pPort,
+ Addr );
+ }
+ else {
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ "Invalid" );
+ }
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // End
+ //
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ "</code></td><td align=\"right\"><code>" );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ if ( bValid ) {
+ //
+ // Determine the end address
+ //
+ Mask = Mtrr.Variables.Mtrr[ Count ].Mask;
+ Value = Mask;
+ ShiftCount = 0;
+ while ( 0 < Value ) {
+ Value <<= 1;
+ ShiftCount += 1;
+ }
+ Value = 1;
+ Value <<= 64 - ShiftCount;
+ Value -= 1;
+ Value = ~Value;
+ Value |= Mask;
+ Value &= ~VARIABLE_MTRR_VALID;
+ Value = ~Value;
+
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ "0x" );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = HttpSendHexValue ( SocketFD,
+ pPort,
+ Addr + Value );
+ }
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Type
+ //
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ "</code></td><td>" );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ if ( bValid ) {
+ Type = Mtrr.Variables.Mtrr[ Count ].Base & 0xFF;
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ ( DIM ( mMemoryType ) > Type )
+ ? mMemoryType [ Type ]
+ : "Reserved" );
+ }
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // End of row
+ //
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ "</td></tr>\r\n" );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ }
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // End of table
+ //
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ "</table>\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/uefi/linaro-edk2/AppPkg/Applications/Sockets/WebServer/PageList.c b/uefi/linaro-edk2/AppPkg/Applications/Sockets/WebServer/PageList.c
new file mode 100644
index 0000000..1e271e5
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/WebServer/PageList.c
@@ -0,0 +1,62 @@
+/**
+ @file
+ List of pages to display
+
+ Copyright (c) 2011-2012, Intel Corporation
+ All rights reserved. This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <WebServer.h>
+
+
+/**
+ List of pages in the system
+**/
+CONST DT_PAGE mPageList[] = {
+
+ //
+ // The index page must be first
+ //
+ { L"/", IndexPage, L"Index of pages" }, ///< List the pages
+
+ //
+ // All other pages follow in alphabetical order
+ //
+ { PAGE_BOOT_SERVICES_TABLE, BootServicesTablePage, L"Boot Services Table" }, ///< Format boot services table
+ { PAGE_CONFIGURATION_TABLE, ConfigurationTablePage, L"Configuration Table" }, ///< Format configuration table
+ { L"/DhcpOptions", DhcpOptionsPage, L"DHCP Options" }, ///< Display the DHCP options
+ { PAGE_ACPI_APIC, AcpiApicPage, L"APIC" }, ///< Format APIC
+ { PAGE_ACPI_BGRT, AcpiBgrtPage, L"BGRT" }, ///< Format BGRT
+ { 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
+ { PAGE_ACPI_HPET, AcpiHpetPage, L"HPET" }, ///< Format HPET
+ { PAGE_ACPI_MCFG, AcpiMcfgPage, L"MCFG" }, ///< Format MCFG
+ { L"/MemoryMap", MemoryMapPage, L"Memory Map" }, ///< Memory list
+#if defined (MDE_CPU_IA32) || defined (MDE_CPU_X64)
+ { L"/MTRRs", MemoryTypeRegistersPage, L"Memory Type Range Registers" }, ///< Memory type range register table
+#endif // Intel
+ { 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
+ { PAGE_ACPI_RSDT, AcpiRsdtPage, L"RSDT - ACPI Root System Description Table" }, ///< Format RSDT
+ { PAGE_RUNTIME_SERVICES_TABLE, RuntimeSservicesTablePage, L"Runtime Services Table" },///< Format runtime services table
+ { PAGE_ACPI_SSDT, AcpiSsdtPage, L"SSDT" }, ///< Format SSDT
+ { L"/SystemTable", SystemTablePage, L"System Table" },///< Format system table
+ { PAGE_ACPI_TCPA, AcpiTcpaPage, L"TCPA" }, ///< Format TCPA
+ { PAGE_ACPI_UEFI, AcpiUefiPage, L"UEFI" } ///< Format UEFI
+};
+
+CONST UINTN mPageCount = DIM ( mPageList );
diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/WebServer/Ports.c b/uefi/linaro-edk2/AppPkg/Applications/Sockets/WebServer/Ports.c
new file mode 100644
index 0000000..f9b6680
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/WebServer/Ports.c
@@ -0,0 +1,136 @@
+/**
+ @file
+ Ports response page
+
+ Copyright (c) 2011-2012, Intel Corporation
+ All rights reserved. This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#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;
+}
diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/WebServer/Reboot.c b/uefi/linaro-edk2/AppPkg/Applications/Sockets/WebServer/Reboot.c
new file mode 100644
index 0000000..2fc8fec
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/WebServer/Reboot.c
@@ -0,0 +1,95 @@
+/**
+ @file
+ Reboot the system
+
+ Copyright (c) 2011-2012, Intel Corporation
+ All rights reserved. This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <WebServer.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+
+
+/**
+ Page to reboot the system
+
+ @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
+RebootPage (
+ IN int SocketFD,
+ IN WSDT_PORT * pPort,
+ OUT BOOLEAN * pbDone
+ )
+{
+ EFI_STATUS Status;
+
+ DBG_ENTER ( );
+
+ //
+ // Send the Reboot page
+ //
+ for ( ; ; ) {
+ //
+ // Send the page header
+ //
+ Status = HttpPageHeader ( SocketFD, pPort, L"Reboot" );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Send the page body
+ //
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ "<h1>Reboot</h1>\r\n"
+ "<p>\r\n"
+ " Ouch! The system is rebooting!\r\n" );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Send the page trailer
+ //
+ Status = HttpPageTrailer ( SocketFD, pPort, pbDone );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Deliver the data to the remote system by
+ // closing the socket
+ //
+ close ( SocketFD );
+
+ //
+ // Attempt to reboot the system
+ //
+ DEBUG (( DEBUG_REQUEST, "Reseting System\r\n" ));
+ gRT->ResetSystem ( EfiResetCold,
+ EFI_SUCCESS,
+ 0,
+ NULL );
+ break;
+ }
+
+ //
+ // Return the operation status
+ //
+ DBG_EXIT_STATUS ( Status );
+ return Status;
+}
diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/WebServer/RuntimeServicesTable.c b/uefi/linaro-edk2/AppPkg/Applications/Sockets/WebServer/RuntimeServicesTable.c
new file mode 100644
index 0000000..d5fed0c
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/WebServer/RuntimeServicesTable.c
@@ -0,0 +1,217 @@
+/**
+ @file
+ Display the runtime services table
+
+ Copyright (c) 2011-2012, Intel Corporation
+ All rights reserved. This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <WebServer.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+
+/**
+ Respond with the runtime services table
+
+ @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
+RuntimeSservicesTablePage (
+ IN int SocketFD,
+ IN WSDT_PORT * pPort,
+ OUT BOOLEAN * pbDone
+ )
+{
+ EFI_STATUS Status;
+
+ DBG_ENTER ( );
+
+ //
+ // Send the runtime services page
+ //
+ for ( ; ; ) {
+ //
+ // Send the page and table header
+ //
+ Status = TableHeader ( SocketFD, pPort, L"Runtime Services Table", gRT );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ ///
+ /// The table header for the EFI Runtime Services Table.
+ ///
+ Status = EfiTableHeader ( SocketFD,
+ pPort,
+ &gRT->Hdr );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Time Services
+ //
+ Status = RowPointer ( SocketFD,
+ pPort,
+ "GetTime",
+ (VOID *)gRT->GetTime,
+ NULL );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowPointer ( SocketFD,
+ pPort,
+ "SetTime",
+ (VOID *)gRT->SetTime,
+ NULL );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowPointer ( SocketFD,
+ pPort,
+ "GetWakeupTime",
+ (VOID *)gRT->GetWakeupTime,
+ NULL );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowPointer ( SocketFD,
+ pPort,
+ "SetWakeupTime",
+ (VOID *)gRT->SetWakeupTime,
+ NULL );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Virtual Memory Services
+ //
+ Status = RowPointer ( SocketFD,
+ pPort,
+ "SetVirtualAddressMap",
+ (VOID *)gRT->SetVirtualAddressMap,
+ NULL );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowPointer ( SocketFD,
+ pPort,
+ "ConvertPointer",
+ (VOID *)gRT->ConvertPointer,
+ NULL );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Variable Services
+ //
+ Status = RowPointer ( SocketFD,
+ pPort,
+ "GetVariable",
+ (VOID *)gRT->GetVariable,
+ NULL );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowPointer ( SocketFD,
+ pPort,
+ "GetNextVariableName",
+ (VOID *)gRT->GetNextVariableName,
+ NULL );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowPointer ( SocketFD,
+ pPort,
+ "SetVariable",
+ (VOID *)gRT->SetVariable,
+ NULL );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Miscellaneous Services
+ //
+ Status = RowPointer ( SocketFD,
+ pPort,
+ "GetNextHighNonotonicCount",
+ (VOID *)gRT->GetNextHighMonotonicCount,
+ NULL );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowPointer ( SocketFD,
+ pPort,
+ "ResetSystem",
+ (VOID *)gRT->ResetSystem,
+ NULL );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Determine if the structures supports 2.0 services
+ //
+ if ( 2 <= ( gRT->Hdr.Revision >> 16 )) {
+ //
+ // UEFI 2.0 Capsule Services
+ //
+ Status = RowPointer ( SocketFD,
+ pPort,
+ "UpdateCapsule",
+ (VOID *)gRT->UpdateCapsule,
+ NULL );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = RowPointer ( SocketFD,
+ pPort,
+ "QueryCapsuleCapabilities",
+ (VOID *)gRT->QueryCapsuleCapabilities,
+ NULL );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Miscellaneous UEFI 2.0 Service
+ //
+ Status = RowPointer ( SocketFD,
+ pPort,
+ "QueryVariableInfo",
+ (VOID *)gRT->QueryVariableInfo,
+ NULL );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ }
+
+ //
+ // Build the table trailer
+ //
+ Status = TableTrailer ( SocketFD,
+ pPort,
+ pbDone );
+ break;
+ }
+
+ //
+ // Return the operation status
+ //
+ DBG_EXIT_STATUS ( Status );
+ return Status;
+}
diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/WebServer/SystemTable.c b/uefi/linaro-edk2/AppPkg/Applications/Sockets/WebServer/SystemTable.c
new file mode 100644
index 0000000..83f6030
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/WebServer/SystemTable.c
@@ -0,0 +1,853 @@
+/**
+ @file
+ Display the system table
+
+ Copyright (c) 2011-2012, Intel Corporation
+ All rights reserved. This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <WebServer.h>
+
+
+/**
+ Display the EFI Table Header
+
+ @param [in] SocketFD The socket's file descriptor to add to the list.
+ @param [in] pPort The WSDT_PORT structure address
+ @param [in] pHeader Address of the EFI_TABLE_HEADER structure
+
+ @retval EFI_SUCCESS The request was successfully processed
+
+**/
+EFI_STATUS
+EfiTableHeader (
+ IN int SocketFD,
+ IN WSDT_PORT * pPort,
+ IN EFI_TABLE_HEADER * pHeader
+ )
+{
+ EFI_STATUS Status;
+
+ DBG_ENTER ( );
+
+ //
+ // Send the handles page
+ //
+ for ( ; ; ) {
+ ///
+ /// A 64-bit signature that identifies the type of table that follows.
+ /// Unique signatures have been generated for the EFI System Table,
+ /// the EFI Boot Services Table, and the EFI Runtime Services Table.
+ ///
+ Status = RowHexValue ( SocketFD,
+ pPort,
+ "Hdr.Signature",
+ pHeader->Signature,
+ NULL );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ ///
+ /// The revision of the EFI Specification to which this table
+ /// conforms. The upper 16 bits of this field contain the major
+ /// revision value, and the lower 16 bits contain the minor revision
+ /// value. The minor revision values are limited to the range of 00..99.
+ ///
+ Status = RowRevision ( SocketFD,
+ pPort,
+ "Hdr.Revision",
+ pHeader->Revision );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ ///
+ /// The size, in bytes, of the entire table including the EFI_TABLE_HEADER.
+ ///
+ Status = RowDecimalValue ( SocketFD,
+ pPort,
+ "Hdr.HeaderSize",
+ pHeader->HeaderSize );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ ///
+ /// The 32-bit CRC for the entire table. This value is computed by
+ /// setting this field to 0, and computing the 32-bit CRC for HeaderSize bytes.
+ ///
+ Status = RowHexValue ( SocketFD,
+ pPort,
+ "Hdr.CRC",
+ pHeader->CRC32,
+ NULL );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ ///
+ /// Reserved field that must be set to 0.
+ ///
+ Status = RowHexValue ( SocketFD,
+ pPort,
+ "Hdr.Reserved",
+ pHeader->Reserved,
+ NULL );
+ break;
+ }
+
+ //
+ // Return the operation status
+ //
+ DBG_EXIT_STATUS ( Status );
+ return Status;
+}
+
+
+/**
+ Display a row containing a decimal value
+
+ @param [in] SocketFD The socket's file descriptor to add to the list.
+ @param [in] pPort The WSDT_PORT structure address
+ @param [in] pName Address of a zero terminated name string
+ @param [in] Value The value to display
+
+ @retval EFI_SUCCESS The request was successfully processed
+
+**/
+EFI_STATUS
+RowDecimalValue (
+ IN int SocketFD,
+ IN WSDT_PORT * pPort,
+ IN CONST CHAR8 * pName,
+ IN UINT64 Value
+ )
+{
+ EFI_STATUS Status;
+
+ DBG_ENTER ( );
+
+ //
+ // Use for/break instead of goto
+ //
+ for ( ; ; ) {
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ "<tr><td>" );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ pName );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ "</td><td><code>" );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = HttpSendValue ( SocketFD,
+ pPort,
+ Value );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ "</code></td></tr>\r\n" );
+ break;
+ }
+
+ //
+ // Return the operation status
+ //
+ DBG_EXIT_STATUS ( Status );
+ return Status;
+}
+
+
+/**
+ Display a row containing a hex value
+
+ @param [in] SocketFD The socket's file descriptor to add to the list.
+ @param [in] pPort The WSDT_PORT structure address
+ @param [in] pName Address of a zero terminated name string
+ @param [in] Value The value to display
+ @param [in] pWebPage Address of a zero terminated web page name
+
+ @retval EFI_SUCCESS The request was successfully processed
+
+**/
+EFI_STATUS
+RowHexValue (
+ IN int SocketFD,
+ IN WSDT_PORT * pPort,
+ IN CONST CHAR8 * pName,
+ IN UINT64 Value,
+ IN CONST CHAR16 * pWebPage
+ )
+{
+ EFI_STATUS Status;
+
+ DBG_ENTER ( );
+
+ //
+ // Use for/break instead of goto
+ //
+ for ( ; ; ) {
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ "<tr><td>" );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ pName );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ "</td><td><code>0x" );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ if ( NULL != pWebPage ) {
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ "<a target=\"_blank\" href=\"" );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = HttpSendUnicodeString ( SocketFD,
+ pPort,
+ pWebPage );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ "\">" );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ }
+ Status = HttpSendHexValue ( SocketFD,
+ pPort,
+ Value );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ if ( NULL != pWebPage ) {
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ "</a>" );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ }
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ "</code></td></tr>\r\n" );
+ break;
+ }
+
+ //
+ // Return the operation status
+ //
+ DBG_EXIT_STATUS ( Status );
+ return Status;
+}
+
+
+/**
+ Display a row containing a pointer
+
+ @param [in] SocketFD The socket's file descriptor to add to the list.
+ @param [in] pPort The WSDT_PORT structure address
+ @param [in] pName Address of a zero terminated name string
+ @param [in] pAddress The address to display
+ @param [in] pWebPage Address of a zero terminated web page name
+
+ @retval EFI_SUCCESS The request was successfully processed
+
+**/
+EFI_STATUS
+RowPointer (
+ IN int SocketFD,
+ IN WSDT_PORT * pPort,
+ IN CONST CHAR8 * pName,
+ IN CONST VOID * pAddress,
+ IN CONST CHAR16 * pWebPage
+ )
+{
+ EFI_STATUS Status;
+
+ DBG_ENTER ( );
+
+ //
+ // Use for/break instead of goto
+ //
+ for ( ; ; ) {
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ "<tr><td>" );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ pName );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ "</td><td><code>" );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ if ( NULL != pWebPage ) {
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ "<a target=\"_blank\" href=\"" );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = HttpSendUnicodeString ( SocketFD,
+ pPort,
+ pWebPage );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ "\">" );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ }
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ "0x" );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = HttpSendHexBits ( SocketFD,
+ pPort,
+ sizeof ( pAddress ) * 8,
+ (UINT64)(UINTN)pAddress );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ if ( NULL != pWebPage ) {
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ "</a>" );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ }
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ "</code></td></tr>\r\n" );
+ break;
+ }
+
+ //
+ // Return the operation status
+ //
+ DBG_EXIT_STATUS ( Status );
+ return Status;
+}
+
+
+/**
+ Display a row containing a revision
+
+ @param [in] SocketFD The socket's file descriptor to add to the list.
+ @param [in] pPort The WSDT_PORT structure address
+ @param [in] pName Address of a zero terminated name string
+ @param [in] Revision The revision to display
+
+ @retval EFI_SUCCESS The request was successfully processed
+
+**/
+EFI_STATUS
+RowRevision (
+ IN int SocketFD,
+ IN WSDT_PORT * pPort,
+ IN CONST CHAR8 * pName,
+ IN UINT32 Revision
+ )
+{
+ EFI_STATUS Status;
+
+ DBG_ENTER ( );
+
+ //
+ // Use for/break instead of goto
+ //
+ for ( ; ; ) {
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ "<tr><td>" );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ pName );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ "</td><td><code>" );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = HttpSendValue ( SocketFD,
+ pPort,
+ Revision >> 16 );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = HttpSendByte ( SocketFD,
+ pPort,
+ '.' );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = HttpSendValue ( SocketFD,
+ pPort,
+ Revision & 0xFFFF );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ "</code></td></tr>\r\n" );
+ break;
+ }
+
+ //
+ // Return the operation status
+ //
+ DBG_EXIT_STATUS ( Status );
+ return Status;
+}
+
+
+/**
+ Display a row containing a unicode string
+
+ @param [in] SocketFD The socket's file descriptor to add to the list.
+ @param [in] pPort The WSDT_PORT structure address
+ @param [in] pName Address of a zero terminated name string
+ @param [in] pString Address of a zero terminated unicode string
+
+ @retval EFI_SUCCESS The request was successfully processed
+
+**/
+EFI_STATUS
+RowUnicodeString (
+ IN int SocketFD,
+ IN WSDT_PORT * pPort,
+ IN CONST CHAR8 * pName,
+ IN CONST CHAR16 * pString
+ )
+{
+ EFI_STATUS Status;
+
+ DBG_ENTER ( );
+
+ //
+ // Use for/break instead of goto
+ //
+ for ( ; ; ) {
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ "<tr><td>" );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ pName );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ "</td><td>" );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = HttpSendUnicodeString ( SocketFD,
+ pPort,
+ pString );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ "</td></tr>\r\n" );
+ break;
+ }
+
+ //
+ // Return the operation status
+ //
+ DBG_EXIT_STATUS ( Status );
+ return Status;
+}
+
+
+/**
+ Start the table page
+
+ @param [in] SocketFD The socket's file descriptor to add to the list.
+ @param [in] pPort The WSDT_PORT structure address
+ @param [in] pName Address of a zero terminated name string
+ @param [in] pTable Address of the table
+
+ @retval EFI_SUCCESS The request was successfully processed
+
+**/
+EFI_STATUS
+TableHeader (
+ IN int SocketFD,
+ IN WSDT_PORT * pPort,
+ IN CONST CHAR16 * pName,
+ IN CONST VOID * pTable
+ )
+{
+ EFI_STATUS Status;
+
+ DBG_ENTER ( );
+
+ //
+ // Use for/break instead of goto
+ //
+ for ( ; ; ) {
+ //
+ // Send the page header
+ //
+ Status = HttpPageHeader ( SocketFD, pPort, pName );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Build the table header
+ //
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ "<h1>" );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = HttpSendUnicodeString ( SocketFD,
+ pPort,
+ pName );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ if ( NULL != pTable ) {
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ ": 0x" );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ Status = HttpSendHexBits ( SocketFD,
+ pPort,
+ sizeof ( pTable ) * 8,
+ (UINT64)(UINTN)pTable );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+ }
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ "</h1>\r\n"
+ "<table border=\"1\">\r\n"
+ " <tr bgcolor=\"c0c0ff\"><th>Field Name</th><th>Value</th></tr>\r\n" );
+ break;
+ }
+
+ //
+ // Return the operation status
+ //
+ DBG_EXIT_STATUS ( Status );
+ return Status;
+}
+
+
+/**
+ End the table 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
+TableTrailer (
+ IN int SocketFD,
+ IN WSDT_PORT * pPort,
+ OUT BOOLEAN *pbDone
+ )
+{
+ EFI_STATUS Status;
+
+ DBG_ENTER ( );
+
+ //
+ // Use for/break instead of goto
+ //
+ for ( ; ; ) {
+ //
+ // Build the table trailer
+ //
+ Status = HttpSendAnsiString ( SocketFD,
+ pPort,
+ "</table>\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;
+}
+
+
+/**
+ Respond with the system table
+
+ @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
+SystemTablePage (
+ IN int SocketFD,
+ IN WSDT_PORT * pPort,
+ OUT BOOLEAN * pbDone
+ )
+{
+ EFI_STATUS Status;
+
+ DBG_ENTER ( );
+
+ //
+ // Send the system table page
+ //
+ for ( ; ; ) {
+ //
+ // Send the page and table header
+ //
+ Status = TableHeader ( SocketFD, pPort, L"System Table", gST );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ ///
+ /// The table header for the EFI System Table.
+ ///
+ Status = EfiTableHeader ( SocketFD,
+ pPort,
+ &gST->Hdr );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ ///
+ /// A pointer to a null terminated string that identifies the vendor
+ /// that produces the system firmware for the platform.
+ ///
+ Status = RowUnicodeString ( SocketFD,
+ pPort,
+ "FirmwareVendor",
+ gST->FirmwareVendor );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ ///
+ /// A firmware vendor specific value that identifies the revision
+ /// of the system firmware for the platform.
+ ///
+ Status = RowRevision ( SocketFD,
+ pPort,
+ "FirmwareRevision",
+ gST->FirmwareRevision );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ ///
+ /// The handle for the active console input device. This handle must support
+ /// EFI_SIMPLE_TEXT_INPUT_PROTOCOL and EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL.
+ ///
+ Status = RowPointer ( SocketFD,
+ pPort,
+ "ConsoleInHandle",
+ (VOID *)gST->ConsoleInHandle,
+ NULL );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ ///
+ /// A pointer to the EFI_SIMPLE_TEXT_INPUT_PROTOCOL interface that is
+ /// associated with ConsoleInHandle.
+ ///
+ Status = RowPointer ( SocketFD,
+ pPort,
+ "ConIn",
+ (VOID *)gST->ConIn,
+ NULL );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ ///
+ /// The handle for the active console output device.
+ ///
+ Status = RowPointer ( SocketFD,
+ pPort,
+ "ConsoleOutHandle",
+ (VOID *)gST->ConsoleOutHandle,
+ NULL );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ ///
+ /// A pointer to the EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL interface
+ /// that is associated with ConsoleOutHandle.
+ ///
+ Status = RowPointer ( SocketFD,
+ pPort,
+ "ConOut",
+ (VOID *)gST->ConOut,
+ NULL );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ ///
+ /// The handle for the active standard error console device.
+ /// This handle must support the EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.
+ ///
+ Status = RowPointer ( SocketFD,
+ pPort,
+ "StandardErrorHandle",
+ (VOID *)gST->StandardErrorHandle,
+ NULL );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ ///
+ /// A pointer to the EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL interface
+ /// that is associated with StandardErrorHandle.
+ ///
+ Status = RowPointer ( SocketFD,
+ pPort,
+ "StdErr",
+ (VOID *)gST->StdErr,
+ NULL );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ ///
+ /// A pointer to the EFI Runtime Services Table.
+ ///
+ Status = RowPointer ( SocketFD,
+ pPort,
+ "RuntimeServices",
+ (VOID *)gST->RuntimeServices,
+ PAGE_RUNTIME_SERVICES_TABLE );
+
+ ///
+ /// A pointer to the EFI Boot Services Table.
+ ///
+ Status = RowPointer ( SocketFD,
+ pPort,
+ "BootServices",
+ (VOID *)gST->BootServices,
+ PAGE_BOOT_SERVICES_TABLE );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ ///
+ /// The number of system configuration tables in the buffer ConfigurationTable.
+ ///
+ Status = RowDecimalValue ( SocketFD,
+ pPort,
+ "NumberOfTableEntries",
+ gST->NumberOfTableEntries );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ ///
+ /// A pointer to the system configuration tables.
+ /// The number of entries in the table is NumberOfTableEntries.
+ ///
+ Status = RowPointer ( SocketFD,
+ pPort,
+ "ConfigurationTable",
+ (VOID *)gST->ConfigurationTable,
+ PAGE_CONFIGURATION_TABLE );
+ if ( EFI_ERROR ( Status )) {
+ break;
+ }
+
+ //
+ // Build the table trailer
+ //
+ Status = TableTrailer ( SocketFD,
+ pPort,
+ pbDone );
+ break;
+ }
+
+ //
+ // Return the operation status
+ //
+ DBG_EXIT_STATUS ( Status );
+ return Status;
+}
diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/WebServer/WebServer.c b/uefi/linaro-edk2/AppPkg/Applications/Sockets/WebServer/WebServer.c
new file mode 100644
index 0000000..f8a2d3a
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/WebServer/WebServer.c
@@ -0,0 +1,782 @@
+/**
+ @file
+ Web server application
+
+ Copyright (c) 2011-2012, Intel Corporation
+ All rights reserved. This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <WebServer.h>
+
+DT_WEB_SERVER mWebServer; ///< Web server's control structure
+
+
+/**
+ Add a port to the list of ports to be polled.
+
+ @param [in] pWebServer The web server control structure address.
+
+ @param [in] SocketFD The socket's file descriptor to add to the list.
+
+ @retval EFI_SUCCESS The port was successfully added
+ @retval EFI_NO_RESOURCES Insufficient memory to add the port
+
+**/
+EFI_STATUS
+PortAdd (
+ IN DT_WEB_SERVER * pWebServer,
+ IN int SocketFD
+ )
+{
+ nfds_t Index;
+ size_t LengthInBytes;
+ nfds_t MaxEntries;
+ nfds_t MaxEntriesNew;
+ struct pollfd * pFdList;
+ struct pollfd * pFdListNew;
+ WSDT_PORT ** ppPortListNew;
+ WSDT_PORT * pPort;
+ EFI_STATUS Status;
+
+ DBG_ENTER ( );
+
+ //
+ // Use for/break instead of goto
+ //
+ for ( ; ; ) {
+ //
+ // Assume success
+ //
+ Status = EFI_SUCCESS;
+
+ //
+ // Create a new list if necessary
+ //
+ pFdList = pWebServer->pFdList;
+ MaxEntries = pWebServer->MaxEntries;
+ if ( pWebServer->Entries >= MaxEntries ) {
+ MaxEntriesNew = 16 + MaxEntries;
+
+ //
+ // The current FD list is full
+ // Allocate a new FD list
+ //
+ LengthInBytes = sizeof ( *pFdList ) * MaxEntriesNew;
+ Status = gBS->AllocatePool ( EfiRuntimeServicesData,
+ LengthInBytes,
+ (VOID **)&pFdListNew );
+ if ( EFI_ERROR ( Status )) {
+ DEBUG (( DEBUG_ERROR | DEBUG_POOL,
+ "ERROR - Failed to allocate the FD list, Status: %r\r\n",
+ Status ));
+ break;
+ }
+
+ //
+ // Allocate a new port list
+ //
+ LengthInBytes = sizeof ( *ppPortListNew ) * MaxEntriesNew;
+ Status = gBS->AllocatePool ( EfiRuntimeServicesData,
+ LengthInBytes,
+ (VOID **) &ppPortListNew );
+ if ( EFI_ERROR ( Status )) {
+ DEBUG (( DEBUG_ERROR | DEBUG_POOL,
+ "ERROR - Failed to allocate the port list, Status: %r\r\n",
+ Status ));
+
+ //
+ // Free the new FD list
+ //
+ gBS->FreePool ( pFdListNew );
+ break;
+ }
+
+ //
+ // Duplicate the FD list
+ //
+ Index = MaxEntries;
+ if ( NULL != pFdList ) {
+ CopyMem ( pFdListNew,
+ pFdList,
+ Index * sizeof ( *pFdList ));
+ }
+
+ //
+ // Initialize the new entries in the FD list
+ //
+ for ( ; MaxEntriesNew > Index; Index++ ) {
+ pFdListNew[ Index ].fd = -1;
+ pFdListNew[ Index ].events = 0;
+ pFdListNew[ Index ].revents = 0;
+ }
+
+ //
+ // Free the old FD list
+ //
+ if ( NULL != pFdList ) {
+ gBS->FreePool ( pFdList );
+ }
+
+ //
+ // Switch to the new FD list
+ //
+ pWebServer->pFdList = pFdListNew;
+ pFdList = pWebServer->pFdList;
+
+ //
+ // Duplicate the port list
+ //
+ Index = MaxEntries;
+ if ( NULL != pWebServer->ppPortList ) {
+ CopyMem ( ppPortListNew,
+ pWebServer->ppPortList,
+ Index * sizeof ( *ppPortListNew ));
+ }
+
+ //
+ // Initialize the new entries in the port list
+ //
+ for ( ; MaxEntriesNew > Index; Index++ ) {
+ ppPortListNew[ Index ] = NULL;
+ }
+
+ //
+ // Free the old port list
+ //
+ if ( NULL != pWebServer->ppPortList ) {
+ gBS->FreePool ( pWebServer->ppPortList );
+ }
+
+ //
+ // Switch to the new port list
+ //
+ pWebServer->ppPortList = ppPortListNew;
+
+ //
+ // Update the list size
+ //
+ pWebServer->MaxEntries = MaxEntriesNew;
+ }
+
+ //
+ // Allocate a new port
+ //
+ LengthInBytes = sizeof ( *pPort );
+ Status = gBS->AllocatePool ( EfiRuntimeServicesData,
+ LengthInBytes,
+ (VOID **)&pPort );
+ if ( EFI_ERROR ( Status )) {
+ DEBUG (( DEBUG_ERROR | DEBUG_POOL,
+ "ERROR - Failed to allocate the port, Status: %r\r\n",
+ Status ));
+ break;
+ }
+
+ //
+ // Initialize the port
+ //
+ pPort->RequestLength = 0;
+ pPort->TxBytes = 0;
+
+ //
+ // Add the socket to the FD list
+ //
+ pFdList[ pWebServer->Entries ].fd = SocketFD;
+ pFdList[ pWebServer->Entries ].events = POLLRDNORM
+ | POLLHUP;
+ pFdList[ pWebServer->Entries ].revents = 0;
+
+ //
+ // Add the port to the port list
+ //
+ pWebServer->ppPortList[ pWebServer->Entries ] = pPort;
+
+ //
+ // Account for the new entry
+ //
+ pWebServer->Entries += 1;
+ DEBUG (( DEBUG_PORT_WORK | DEBUG_INFO,
+ "WebServer handling %d ports\r\n",
+ pWebServer->Entries ));
+
+ //
+ // All done
+ //
+ break;
+ }
+
+ //
+ // Return the operation status
+ //
+ DBG_EXIT_STATUS ( Status );
+ return Status;
+}
+
+
+/**
+ Remove a port from the list of ports to be polled.
+
+ @param [in] pWebServer The web server control structure address.
+
+ @param [in] SocketFD The socket's file descriptor to add to the list.
+
+**/
+VOID
+PortRemove (
+ IN DT_WEB_SERVER * pWebServer,
+ IN int SocketFD
+ )
+{
+ nfds_t Entries;
+ nfds_t Index;
+ struct pollfd * pFdList;
+ WSDT_PORT ** ppPortList;
+
+ DBG_ENTER ( );
+
+ //
+ // Attempt to remove the entry from the list
+ //
+ Entries = pWebServer->Entries;
+ pFdList = pWebServer->pFdList;
+ ppPortList = pWebServer->ppPortList;
+ for ( Index = 0; Entries > Index; Index++ ) {
+ //
+ // Locate the specified socket file descriptor
+ //
+ if ( SocketFD == pFdList[ Index ].fd ) {
+ //
+ // Determine if this is the listen port
+ //
+ if ( SocketFD == pWebServer->HttpListenPort ) {
+ pWebServer->HttpListenPort = -1;
+ }
+
+ //
+ // Close the socket
+ //
+ close ( SocketFD );
+
+ //
+ // Free the port structure
+ //
+ gBS->FreePool ( ppPortList[ Index ]);
+
+ //
+ // Remove this port from the list by copying
+ // the rest of the list down one entry
+ //
+ Entries -= 1;
+ for ( ; Entries > Index; Index++ ) {
+ pFdList[ Index ] = pFdList[ Index + 1 ];
+ ppPortList[ Index ] = ppPortList[ Index + 1 ];
+ }
+ pFdList[ Index ].fd = -1;
+ pFdList[ Index ].events = 0;
+ pFdList[ Index ].revents = 0;
+ ppPortList[ Index ] = NULL;
+
+ //
+ // Update the number of entries in the list
+ //
+ pWebServer->Entries = Entries;
+ DEBUG (( DEBUG_PORT_WORK | DEBUG_INFO,
+ "WebServer handling %d ports\r\n",
+ pWebServer->Entries ));
+ break;
+ }
+ }
+
+ DBG_EXIT ( );
+}
+
+
+/**
+ Process the work for the sockets.
+
+ @param [in] pWebServer The web server control structure address.
+
+ @param [in] SocketFD The socket's file descriptor to add to the list.
+
+ @param [in] events everts is a bitmask of the work to be done
+
+ @param [in] pPort The address of a WSDT_PORT structure
+
+ @retval EFI_SUCCESS The operation was successful
+ @retval EFI_DEVICE_ERROR Error, close the port
+
+**/
+EFI_STATUS
+PortWork (
+ IN DT_WEB_SERVER * pWebServer,
+ IN int SocketFD,
+ IN INTN events,
+ IN WSDT_PORT * pPort
+ )
+{
+ BOOLEAN bDone;
+ size_t LengthInBytes;
+ int NewSocket;
+ EFI_STATUS OpStatus;
+ struct sockaddr_in6 RemoteAddress;
+ socklen_t RemoteAddressLength;
+ EFI_STATUS Status;
+
+ DEBUG (( DEBUG_PORT_WORK, "Entering PortWork\r\n" ));
+
+ //
+ // Assume success
+ //
+ OpStatus = EFI_SUCCESS;
+
+ //
+ // Handle input events
+ //
+ if ( 0 != ( events & POLLRDNORM )) {
+ //
+ // Determine if this is a connection attempt
+ //
+ if (( SocketFD == pWebServer->HttpListenPort )
+ || ( SocketFD == pWebServer->HttpListenPort6 )) {
+ //
+ // Handle connection attempts
+ // Accepts arrive as read events
+ //
+ RemoteAddressLength = sizeof ( RemoteAddress );
+ NewSocket = accept ( SocketFD,
+ (struct sockaddr *)&RemoteAddress,
+ &RemoteAddressLength );
+ if ( -1 != NewSocket ) {
+ if ( 0 != NewSocket ) {
+ //
+ // Add this port to the list monitored by the web server
+ //
+ Status = PortAdd ( pWebServer, NewSocket );
+ if ( EFI_ERROR ( Status )) {
+ DEBUG (( DEBUG_ERROR,
+ "ERROR - Failed to add the port 0x%08x, Status: %r\r\n",
+ NewSocket,
+ Status ));
+
+ //
+ // Done with the new socket
+ //
+ close ( NewSocket );
+ }
+ }
+ else {
+ DEBUG (( DEBUG_ERROR,
+ "ERROR - Socket not available!\r\n" ));
+ }
+
+ //
+ // Leave the listen port open
+ //
+ }
+ else {
+ //
+ // Listen port error
+ // Close the listen port by returning error status
+ //
+ OpStatus = EFI_DEVICE_ERROR;
+ DEBUG (( DEBUG_ERROR,
+ "ERROR - Failed to accept new connection, errno: 0x%08x\r\n",
+ errno ));
+ }
+ }
+ else {
+ //
+ // Handle the data received event
+ //
+ if ( 0 == pPort->RequestLength ) {
+ //
+ // Receive the page request
+ //
+ pPort->RequestLength = recv ( SocketFD,
+ &pPort->Request[0],
+ DIM ( pPort->Request ),
+ 0 );
+ if ( -1 == pPort->RequestLength ) {
+ //
+ // Receive error detected
+ // Close the port
+ //
+ OpStatus = EFI_DEVICE_ERROR;
+ }
+ else {
+ DEBUG (( DEBUG_REQUEST,
+ "0x%08x: Socket - Received %d bytes of HTTP request\r\n",
+ SocketFD,
+ pPort->RequestLength ));
+
+ //
+ // Process the request
+ //
+ OpStatus = HttpRequest ( SocketFD, pPort, &bDone );
+ if ( bDone ) {
+ //
+ // Notify the upper layer to close the socket
+ //
+ OpStatus = EFI_DEVICE_ERROR;
+ }
+ }
+ }
+ else {
+ //
+ // Receive the file data
+ //
+ LengthInBytes = recv ( SocketFD,
+ &pPort->RxBuffer[0],
+ DIM ( pPort->RxBuffer ),
+ 0 );
+ if ( -1 == LengthInBytes ) {
+ //
+ // Receive error detected
+ // Close the port
+ //
+ OpStatus = EFI_DEVICE_ERROR;
+ }
+ else {
+ DEBUG (( DEBUG_REQUEST,
+ "0x%08x: Socket - Received %d bytes of file data\r\n",
+ SocketFD,
+ LengthInBytes ));
+
+ //
+ // TODO: Process the file data
+ //
+ }
+ }
+ }
+ }
+
+ //
+ // Handle the close event
+ //
+ if ( 0 != ( events & POLLHUP )) {
+ //
+ // Close the port
+ //
+ OpStatus = EFI_DEVICE_ERROR;
+ }
+
+ //
+ // Return the operation status
+ //
+ DEBUG (( DEBUG_PORT_WORK,
+ "Exiting PortWork, Status: %r\r\n",
+ OpStatus ));
+ return OpStatus;
+}
+
+
+/**
+ Scan the list of sockets and process any pending work
+
+ @param [in] pWebServer The web server control structure address.
+
+**/
+VOID
+SocketPoll (
+ IN DT_WEB_SERVER * pWebServer
+ )
+{
+ int FDCount;
+ struct pollfd * pPoll;
+ WSDT_PORT ** ppPort;
+ EFI_STATUS Status;
+
+ DEBUG (( DEBUG_SOCKET_POLL, "Entering SocketPoll\r\n" ));
+
+ //
+ // Determine if any ports are active
+ //
+ FDCount = poll ( pWebServer->pFdList,
+ pWebServer->Entries,
+ CLIENT_POLL_DELAY );
+ if ( -1 == FDCount ) {
+ DEBUG (( DEBUG_ERROR | DEBUG_SOCKET_POLL,
+ "ERROR - errno: %d\r\n",
+ errno ));
+ }
+
+ pPoll = pWebServer->pFdList;
+ ppPort = pWebServer->ppPortList;
+ while ( 0 < FDCount ) {
+ //
+ // Walk the list of ports to determine what work needs to be done
+ //
+ if ( 0 != pPoll->revents ) {
+ //
+ // Process this port
+ //
+ Status = PortWork ( pWebServer,
+ pPoll->fd,
+ pPoll->revents,
+ *ppPort );
+ pPoll->revents = 0;
+
+ //
+ // Close the port if necessary
+ //
+ if ( EFI_ERROR ( Status )) {
+ PortRemove ( pWebServer, pPoll->fd );
+ pPoll -= 1;
+ ppPort -= 1;
+ }
+
+ //
+ // Account for this file descriptor
+ //
+ FDCount -= 1;
+ }
+
+ //
+ // Set the next port
+ //
+ pPoll += 1;
+ ppPort += 1;
+ }
+
+ DEBUG (( DEBUG_SOCKET_POLL, "Exiting SocketPoll\r\n" ));
+}
+
+
+/**
+ Create an HTTP port for the web server
+
+ 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.
+
+ After the HTTP port is created, the socket layer will manage the
+ 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] 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
+WebServerListen (
+ IN DT_WEB_SERVER * pWebServer,
+ IN sa_family_t AddressFamily,
+ IN int Protocol,
+ IN UINT16 HttpPort,
+ OUT int * pPort
+ )
+{
+ union {
+ struct sockaddr_in v4;
+ struct sockaddr_in6 v6;
+ } WebServerAddress;
+ int SocketStatus;
+ EFI_STATUS Status;
+
+ DEBUG (( DEBUG_SERVER_LISTEN, "Entering WebServerListen\r\n" ));
+
+ //
+ // Attempt to create the socket for the web server
+ //
+ * 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;
+ }
+
+ //
+ // Bind the socket to the HTTP port
+ //
+ SocketStatus = bind ( *pPort,
+ (struct sockaddr *) &WebServerAddress,
+ WebServerAddress.v4.sin_len );
+ if ( -1 != SocketStatus ) {
+ //
+ // Enable connections to the HTTP port
+ //
+ SocketStatus = listen ( *pPort, SOMAXCONN );
+ if ( -1 != SocketStatus ) {
+ //
+ // Add the HTTP port to the list of ports to poll
+ //
+ 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 ));
+ }
+ }
+ }
+
+ //
+ // Release the socket if necessary
+ //
+ if ( -1 == SocketStatus ) {
+ close ( *pPort );
+ *pPort = -1;
+ }
+ }
+
+ DEBUG (( DEBUG_SERVER_LISTEN, "Exiting WebServerListen\r\n" ));
+}
+
+
+/**
+ Entry point for the web server application.
+
+ @param [in] Argc The number of arguments
+ @param [in] Argv The argument value array
+
+ @retval 0 The application exited normally.
+ @retval Other An error occurred.
+**/
+int
+main (
+ IN int Argc,
+ 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
+ //
+ pWebServer = &mWebServer;
+ Status = gBS->CreateEvent ( EVT_TIMER,
+ TPL_WEB_SERVER,
+ NULL,
+ NULL,
+ &pWebServer->TimerEvent );
+ if ( !EFI_ERROR ( Status )) {
+ TriggerTime = HTTP_PORT_POLL_DELAY * ( 1000 * 10 );
+ Status = gBS->SetTimer ( pWebServer->TimerEvent,
+ TimerPeriodic,
+ TriggerTime );
+ if ( !EFI_ERROR ( Status )) {
+ //
+ // Run the web server forever
+ //
+ 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
+ // be necessary since it may take some time to get
+ // the IP address and initialize the upper layers
+ // of the network stack.
+ //
+ if (( -1 == pWebServer->HttpListenPort )
+ || ( -1 == pWebServer->HttpListenPort6 )) {
+ do {
+ //
+ // 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 );
+ }
+
+ //
+ // 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 );
+ }
+
+ //
+ // Poll the sockets for activity while both network
+ // connections are connected
+ //
+ 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 );
+
+ //
+ // Stop the timer
+ //
+ gBS->SetTimer ( pWebServer->TimerEvent,
+ TimerCancel,
+ 0 );
+ }
+
+ //
+ // Done with the timer event
+ //
+ gBS->CloseEvent ( pWebServer->TimerEvent );
+ }
+
+ //
+ // Return the final status
+ //
+ DBG_EXIT_STATUS ( Status );
+ return Status;
+}
diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/WebServer/WebServer.h b/uefi/linaro-edk2/AppPkg/Applications/Sockets/WebServer/WebServer.h
new file mode 100644
index 0000000..16c30c8
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/WebServer/WebServer.h
@@ -0,0 +1,1310 @@
+/** @file
+ Definitions for the web server.
+
+ Copyright (c) 2011-2012, Intel Corporation
+ All rights reserved. This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef _WEB_SERVER_H_
+#define _WEB_SERVER_H_
+
+#include <errno.h>
+#include <Uefi.h>
+
+#include <Guid/EventGroup.h>
+
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PcdLib.h>
+#include <Library/UefiApplicationEntryPoint.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiLib.h>
+#include <Protocol/BlockIo.h>
+
+#include <netinet/in.h>
+
+#include <sys/EfiSysCall.h>
+#include <sys/poll.h>
+#include <sys/socket.h>
+
+#if defined(_MSC_VER) // Handle Microsoft VC++ compiler specifics.
+#pragma warning ( disable : 4054 )
+#pragma warning ( disable : 4152 )
+#endif // defined(_MSC_VER)
+
+//------------------------------------------------------------------------------
+// Pages
+//------------------------------------------------------------------------------
+
+#define PAGE_ACPI_APIC L"/APIC"
+#define PAGE_ACPI_BGRT L"/BGRT"
+#define PAGE_ACPI_DSDT L"/DSDT"
+#define PAGE_ACPI_FADT L"/FADT"
+#define PAGE_ACPI_HPET L"/HPET"
+#define PAGE_ACPI_MCFG L"/MCFG"
+#define PAGE_ACPI_RSDP_10B L"/RSDP1.0b"
+#define PAGE_ACPI_RSDP_30 L"/RSDP3.0"
+#define PAGE_ACPI_RSDT L"/RSDT"
+#define PAGE_ACPI_SSDT L"/SSDT"
+#define PAGE_ACPI_TCPA L"/TCPA"
+#define PAGE_ACPI_UEFI L"/UEFI"
+#define PAGE_BOOT_SERVICES_TABLE L"/BootServicesTable"
+#define PAGE_CONFIGURATION_TABLE L"/ConfigurationTable"
+#define PAGE_DXE_SERVICES_TABLE L"/DxeServicesTable"
+#define PAGE_RUNTIME_SERVICES_TABLE L"/RuntimeServicesTable"
+
+//------------------------------------------------------------------------------
+// Signatures
+//------------------------------------------------------------------------------
+
+#define APIC_SIGNATURE 0x43495041
+#define BGRT_SIGNATURE 0x54524742
+#define DSDT_SIGNATURE 0x54445344
+#define FADT_SIGNATURE 0x50434146
+#define HPET_SIGNATURE 0x54455048
+#define MCFG_SIGNATURE 0x4746434d
+#define SSDT_SIGNATURE 0x54445353
+#define TCPA_SIGNATURE 0x41504354
+#define UEFI_SIGNATURE 0x49464555
+
+//------------------------------------------------------------------------------
+// Macros
+//------------------------------------------------------------------------------
+
+#if defined(_MSC_VER) /* Handle Microsoft VC++ compiler specifics. */
+#define DBG_ENTER() DEBUG (( DEBUG_INFO, "Entering " __FUNCTION__ "\n" )) ///< Display routine entry
+#define DBG_EXIT() DEBUG (( DEBUG_INFO, "Exiting " __FUNCTION__ "\n" )) ///< Display routine exit
+#define DBG_EXIT_DEC(Status) DEBUG (( DEBUG_INFO, "Exiting " __FUNCTION__ ", Status: %d\n", Status )) ///< Display routine exit with decimal value
+#define DBG_EXIT_HEX(Status) DEBUG (( DEBUG_INFO, "Exiting " __FUNCTION__ ", Status: 0x%08x\n", Status )) ///< Display routine exit with hex value
+#define DBG_EXIT_STATUS(Status) DEBUG (( DEBUG_INFO, "Exiting " __FUNCTION__ ", Status: %r\n", Status )) ///< Display routine exit with status value
+#define DBG_EXIT_TF(Status) DEBUG (( DEBUG_INFO, "Exiting " __FUNCTION__ ", returning %s\n", (FALSE == Status) ? L"FALSE" : L"TRUE" )) ///< Display routine with TRUE/FALSE value
+#else // _MSC_VER
+#define DBG_ENTER()
+#define DBG_EXIT()
+#define DBG_EXIT_DEC(Status)
+#define DBG_EXIT_HEX(Status)
+#define DBG_EXIT_STATUS(Status)
+#define DBG_EXIT_TF(Status)
+#endif // _MSC_VER
+
+#define DIM(x) ( sizeof ( x ) / sizeof ( x[0] )) ///< Compute the number of entries in an array
+
+//------------------------------------------------------------------------------
+// Constants
+//------------------------------------------------------------------------------
+
+#define DEBUG_SOCKET_POLL 0x00080000 ///< Display the socket poll messages
+#define DEBUG_PORT_WORK 0x00040000 ///< Display the port work 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
+
+#define HTTP_PORT_POLL_DELAY ( 2 * 1000 ) ///< Delay in milliseconds for attempts to open the HTTP port
+#define CLIENT_POLL_DELAY 50 ///< Delay in milliseconds between client polls
+
+#define TPL_WEB_SERVER TPL_CALLBACK ///< TPL for routine synchronization
+
+/**
+ Verify new TPL value
+
+ This macro which is enabled when debug is enabled verifies that
+ the new TPL value is >= the current TPL value.
+**/
+#ifdef VERIFY_TPL
+#undef VERIFY_TPL
+#endif // VERIFY_TPL
+
+#if !defined(MDEPKG_NDEBUG)
+
+#define VERIFY_TPL(tpl) \
+{ \
+ EFI_TPL PreviousTpl; \
+ \
+ PreviousTpl = gBS->RaiseTPL ( TPL_HIGH_LEVEL ); \
+ gBS->RestoreTPL ( PreviousTpl ); \
+ if ( PreviousTpl > tpl ) { \
+ DEBUG (( DEBUG_ERROR, "Current TPL: %d, New TPL: %d\r\n", PreviousTpl, tpl )); \
+ ASSERT ( PreviousTpl <= tpl ); \
+ } \
+}
+
+#else // MDEPKG_NDEBUG
+
+#define VERIFY_TPL(tpl)
+
+#endif // MDEPKG_NDEBUG
+
+#define WEB_SERVER_SIGNATURE SIGNATURE_32 ('W','e','b','S') ///< DT_WEB_SERVER memory signature
+
+#define SPACES_ADDRESS_TO_DATA 2
+#define BYTES_ON_A_LINE 16
+#define SPACES_BETWEEN_BYTES 1
+#define SPACES_DATA_TO_ASCII 2
+
+
+//------------------------------------------------------------------------------
+// Protocol Declarations
+//------------------------------------------------------------------------------
+
+extern EFI_COMPONENT_NAME_PROTOCOL gComponentName; ///< Component name protocol declaration
+extern EFI_COMPONENT_NAME2_PROTOCOL gComponentName2; ///< Component name 2 protocol declaration
+extern EFI_DRIVER_BINDING_PROTOCOL gDriverBinding; ///< Driver binding protocol declaration
+
+//------------------------------------------------------------------------------
+// Data Types
+//------------------------------------------------------------------------------
+
+/**
+ Port control structure
+**/
+typedef struct {
+ //
+ // Buffer management
+ //
+ size_t RequestLength; ///< Request length in bytes
+ size_t TxBytes; ///< Bytes in the TX buffer
+ UINT8 Request[ 65536 ]; ///< Page request
+ UINT8 RxBuffer[ 65536 ]; ///< Receive buffer
+ UINT8 TxBuffer[ 65536 ]; ///< Transmit buffer
+} WSDT_PORT;
+
+/**
+ Web server control structure
+**/
+typedef struct {
+ UINTN Signature; ///< Structure identification
+
+ //
+ // Image attributes
+ //
+ EFI_HANDLE ImageHandle; ///< Image handle
+
+ //
+ // HTTP port management
+ //
+ BOOLEAN bRunning; ///< Web server running
+ EFI_EVENT TimerEvent; ///< Timer to open HTTP 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
+ //
+ nfds_t MaxEntries; ///< Maximum entries in the PortList array
+ nfds_t Entries; ///< The current number of entries in the PortList array
+ struct pollfd * pFdList; ///< List of socket file descriptors
+ WSDT_PORT ** ppPortList; ///< List of port management structures
+} DT_WEB_SERVER;
+
+//#define SERVER_FROM_SERVICE(a) CR (a, DT_WEB_SERVER, ServiceBinding, WEB_SERVER_SIGNATURE) ///< Locate DT_LAYER from service binding
+
+extern DT_WEB_SERVER mWebServer;
+
+/**
+ Process an HTTP request
+
+ @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
+
+**/
+typedef
+EFI_STATUS
+(* PFN_RESPONSE) (
+ IN int SocketFD,
+ IN WSDT_PORT * pPort,
+ IN BOOLEAN * pbDone
+ );
+
+/**
+ Data structure to delcare page support routines
+**/
+typedef struct {
+ UINT16 * pPageName; ///< Name of the page
+ PFN_RESPONSE pfnResponse; ///< Routine to generate the response
+ UINT16 * pDescription; ///< Description of the page
+} DT_PAGE;
+
+extern CONST DT_PAGE mPageList[]; ///< List of pages
+extern CONST UINTN mPageCount; ///< Number of pages
+
+//------------------------------------------------------------------------------
+// Web Pages
+//------------------------------------------------------------------------------
+
+/**
+ Respond with the APIC table
+
+ @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
+AcpiApicPage (
+ IN int SocketFD,
+ IN WSDT_PORT * pPort,
+ OUT BOOLEAN * pbDone
+ );
+
+/**
+ Respond with the BGRT table
+
+ @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
+AcpiBgrtPage (
+ IN int SocketFD,
+ IN WSDT_PORT * pPort,
+ OUT BOOLEAN * pbDone
+ );
+
+/**
+ Respond with the ACPI DSDT table
+
+ @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
+AcpiDsdtPage (
+ IN int SocketFD,
+ IN WSDT_PORT * pPort,
+ OUT BOOLEAN * pbDone
+ );
+
+/**
+ Respond with the ACPI FADT table
+
+ @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
+AcpiFadtPage (
+ IN int SocketFD,
+ IN WSDT_PORT * pPort,
+ OUT BOOLEAN * pbDone
+ );
+
+/**
+ Respond with the HPET table
+
+ @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
+AcpiHpetPage (
+ IN int SocketFD,
+ IN WSDT_PORT * pPort,
+ OUT BOOLEAN * pbDone
+ );
+
+/**
+ Respond with the MCFG table
+
+ @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
+AcpiMcfgPage (
+ IN int SocketFD,
+ IN WSDT_PORT * pPort,
+ OUT BOOLEAN * pbDone
+ );
+
+/**
+ Respond with the ACPI RSDP 1.0b table
+
+ @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
+AcpiRsdp10Page (
+ IN int SocketFD,
+ IN WSDT_PORT * pPort,
+ OUT BOOLEAN * pbDone
+ );
+
+/**
+ Respond with the ACPI RSDP 3.0 table
+
+ @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
+AcpiRsdp30Page (
+ IN int SocketFD,
+ IN WSDT_PORT * pPort,
+ OUT BOOLEAN * pbDone
+ );
+
+/**
+ Respond with the ACPI RSDT table
+
+ @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
+AcpiRsdtPage (
+ IN int SocketFD,
+ IN WSDT_PORT * pPort,
+ OUT BOOLEAN * pbDone
+ );
+
+/**
+ Respond with the SSDT table
+
+ @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
+AcpiSsdtPage (
+ IN int SocketFD,
+ IN WSDT_PORT * pPort,
+ OUT BOOLEAN * pbDone
+ );
+
+/**
+ Respond with the TCPA table
+
+ @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
+AcpiTcpaPage (
+ IN int SocketFD,
+ IN WSDT_PORT * pPort,
+ OUT BOOLEAN * pbDone
+ );
+
+/**
+ Respond with the UEFI table
+
+ @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
+AcpiUefiPage (
+ IN int SocketFD,
+ IN WSDT_PORT * pPort,
+ OUT BOOLEAN * pbDone
+ );
+
+/**
+ Respond with the boot services table
+
+ @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
+BootServicesTablePage (
+ IN int SocketFD,
+ IN WSDT_PORT * pPort,
+ OUT BOOLEAN * pbDone
+ );
+
+/**
+ Respond with the configuration tables
+
+ @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
+ConfigurationTablePage (
+ IN int SocketFD,
+ IN WSDT_PORT * pPort,
+ OUT BOOLEAN * pbDone
+ );
+
+/**
+ Respond with the DHCP options
+
+ @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
+DhcpOptionsPage (
+ IN int SocketFD,
+ IN WSDT_PORT * pPort,
+ OUT BOOLEAN * pbDone
+ );
+
+/**
+ Respond with the DXE services table
+
+ @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
+DxeServicesTablePage (
+ IN int SocketFD,
+ IN WSDT_PORT * pPort,
+ 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
+
+ @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
+FirmwarePage (
+ IN int SocketFD,
+ IN WSDT_PORT * pPort,
+ OUT BOOLEAN * pbDone
+ );
+
+/**
+ Respond with the handles in the system
+
+ @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
+HandlePage (
+ IN int SocketFD,
+ IN WSDT_PORT * pPort,
+ OUT BOOLEAN * pbDone
+ );
+
+/**
+ Respond with the Hello World 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
+HelloPage (
+ IN int SocketFD,
+ IN WSDT_PORT * pPort,
+ OUT BOOLEAN * pbDone
+ );
+
+/**
+ Respond with the list of known pages
+
+ @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
+IndexPage (
+ IN int SocketFD,
+ IN WSDT_PORT * pPort,
+ OUT BOOLEAN * pbDone
+ );
+
+/**
+ Page to display the memory map
+
+ @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
+MemoryMapPage (
+ IN int SocketFD,
+ IN WSDT_PORT * pPort,
+ OUT BOOLEAN * pbDone
+ );
+
+/**
+ Display the memory type registers
+
+ @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
+MemoryTypeRegistersPage (
+ IN int SocketFD,
+ IN WSDT_PORT * pPort,
+ 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
+
+ @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
+RebootPage (
+ IN int SocketFD,
+ IN WSDT_PORT * pPort,
+ OUT BOOLEAN * pbDone
+ );
+
+/**
+ Respond with the runtime services table
+
+ @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
+RuntimeSservicesTablePage (
+ IN int SocketFD,
+ IN WSDT_PORT * pPort,
+ OUT BOOLEAN * pbDone
+ );
+
+/**
+ Respond with the system table
+
+ @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
+SystemTablePage (
+ IN int SocketFD,
+ IN WSDT_PORT * pPort,
+ OUT BOOLEAN * pbDone
+ );
+
+//------------------------------------------------------------------------------
+// Support routines
+//------------------------------------------------------------------------------
+
+/**
+ Display the EFI Table Header
+
+ @param [in] SocketFD The socket's file descriptor to add to the list.
+ @param [in] pPort The WSDT_PORT structure address
+ @param [in] pHeader Address of the EFI_TABLE_HEADER structure
+
+ @retval EFI_SUCCESS The request was successfully processed
+
+**/
+EFI_STATUS
+EfiTableHeader (
+ IN int SocketFD,
+ IN WSDT_PORT * pPort,
+ IN EFI_TABLE_HEADER * pHeader
+ );
+
+/**
+ Buffer the HTTP page header
+
+ @param [in] SocketFD The socket's file descriptor to add to the list.
+ @param [in] pPort The WSDT_PORT structure address
+ @param [in] pTitle A zero terminated Unicode title string
+
+ @retval EFI_SUCCESS The request was successfully processed
+
+**/
+EFI_STATUS
+HttpPageHeader (
+ IN int SocketFD,
+ IN WSDT_PORT * pPort,
+ IN CONST CHAR16 * pTitle
+ );
+
+/**
+ Buffer and send the HTTP page trailer
+
+ @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
+HttpPageTrailer (
+ IN int SocketFD,
+ IN WSDT_PORT * pPort,
+ IN BOOLEAN * pbDone
+ );
+
+/**
+ Process an HTTP request
+
+ @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
+HttpRequest (
+ IN int SocketFD,
+ IN WSDT_PORT * pPort,
+ IN BOOLEAN * pbDone
+ );
+
+/**
+ Buffer data for sending
+
+ @param [in] SocketFD The socket's file descriptor to add to the list.
+ @param [in] pPort The WSDT_PORT structure address
+ @param [in] LengthInBytes Length of valid data in the buffer
+ @param [in] pBuffer Buffer of data to send
+
+ @retval EFI_SUCCESS The request was successfully processed
+
+**/
+EFI_STATUS
+HttpSend (
+ IN int SocketFD,
+ IN WSDT_PORT * pPort,
+ IN size_t LengthInBytes,
+ IN CONST UINT8 * pBuffer
+ );
+
+/**
+ Send an ANSI string
+
+ @param [in] SocketFD The socket's file descriptor to add to the list.
+ @param [in] pPort The WSDT_PORT structure address
+ @param [in] pString A zero terminated Unicode string
+
+ @retval EFI_SUCCESS The request was successfully processed
+
+**/
+EFI_STATUS
+HttpSendAnsiString (
+ IN int SocketFD,
+ IN WSDT_PORT * pPort,
+ IN CONST char * pString
+ );
+
+/**
+ Buffer a single byte
+
+ @param [in] SocketFD The socket's file descriptor to add to the list.
+ @param [in] pPort The WSDT_PORT structure address
+ @param [in] Data The data byte to send
+
+ @retval EFI_SUCCESS The request was successfully processed
+
+**/
+EFI_STATUS
+HttpSendByte (
+ IN int SocketFD,
+ IN WSDT_PORT * pPort,
+ IN UINT8 Data
+ );
+
+/**
+ Display a character
+
+ @param [in] SocketFD The socket's file descriptor to add to the list.
+ @param [in] pPort The WSDT_PORT structure address
+ @param [in] Character Character to display
+ @param [in] pReplacement Replacement character string
+
+ @retval EFI_SUCCESS The request was successfully processed
+
+**/
+EFI_STATUS
+HttpSendCharacter (
+ IN int SocketFD,
+ IN WSDT_PORT * pPort,
+ IN CHAR8 Character,
+ IN CHAR8 * pReplacement
+ );
+
+/**
+ Send a buffer dump
+
+ @param [in] SocketFD The socket's file descriptor to add to the list.
+ @param [in] pPort The WSDT_PORT structure address
+ @param [in] ByteCount The number of bytes to display
+ @param [in] pData Address of the byte array
+
+ @retval EFI_SUCCESS The request was successfully processed
+
+**/
+EFI_STATUS
+HttpSendDump (
+ IN int SocketFD,
+ IN WSDT_PORT * pPort,
+ IN UINTN ByteCount,
+ IN CONST UINT8 * pData
+ );
+
+/**
+ Display a row containing a GUID value
+
+ @param [in] SocketFD The socket's file descriptor to add to the list.
+ @param [in] pPort The WSDT_PORT structure address
+ @param [in] pGuid Address of the GUID to display
+
+ @retval EFI_SUCCESS The request was successfully processed
+
+**/
+EFI_STATUS
+HttpSendGuid (
+ IN int SocketFD,
+ IN WSDT_PORT * pPort,
+ IN CONST EFI_GUID * pGuid
+ );
+
+/**
+ Output a hex value to the HTML page
+
+ @param [in] SocketFD Socket file descriptor
+ @param [in] pPort The WSDT_PORT structure address
+ @param [in] Bits Number of bits to display
+ @param [in] Value Value to display
+
+ @retval EFI_SUCCESS Successfully displayed the address
+**/
+EFI_STATUS
+HttpSendHexBits (
+ IN int SocketFD,
+ IN WSDT_PORT * pPort,
+ IN INT32 Bits,
+ IN UINT64 Value
+ );
+
+/**
+ Output a hex 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
+
+ @retval EFI_SUCCESS Successfully displayed the address
+**/
+EFI_STATUS
+HttpSendHexValue (
+ IN int SocketFD,
+ IN WSDT_PORT * pPort,
+ IN UINT64 Value
+ );
+
+/**
+ Output an IP address to the HTML page
+
+ @param [in] SocketFD Socket file descriptor
+ @param [in] pPort The WSDT_PORT structure address
+ @param [in] pAddress Address of the socket address
+
+ @retval EFI_SUCCESS Successfully displayed the address
+**/
+EFI_STATUS
+HttpSendIpAddress (
+ IN int SocketFD,
+ IN WSDT_PORT * pPort,
+ IN struct sockaddr_in6 * pAddress
+ );
+
+/**
+ Send a Unicode string
+
+ @param [in] SocketFD The socket's file descriptor to add to the list.
+ @param [in] pPort The WSDT_PORT structure address
+ @param [in] pString A zero terminated Unicode string
+
+ @retval EFI_SUCCESS The request was successfully processed
+
+**/
+EFI_STATUS
+HttpSendUnicodeString (
+ IN int SocketFD,
+ IN WSDT_PORT * pPort,
+ IN CONST UINT16 * pString
+ );
+
+/**
+ Output a 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
+
+ @retval EFI_SUCCESS Successfully displayed the address
+**/
+EFI_STATUS
+HttpSendValue (
+ IN int SocketFD,
+ IN WSDT_PORT * pPort,
+ IN UINT64 Value
+ );
+
+/**
+ Display a row containing a decimal value
+
+ @param [in] SocketFD The socket's file descriptor to add to the list.
+ @param [in] pPort The WSDT_PORT structure address
+ @param [in] pName Address of a zero terminated name string
+ @param [in] Value The value to display
+
+ @retval EFI_SUCCESS The request was successfully processed
+
+**/
+EFI_STATUS
+RowDecimalValue (
+ IN int SocketFD,
+ IN WSDT_PORT * pPort,
+ IN CONST CHAR8 * pName,
+ IN UINT64 Value
+ );
+
+/**
+ Display a row containing a GUID value
+
+ @param [in] SocketFD The socket's file descriptor to add to the list.
+ @param [in] pPort The WSDT_PORT structure address
+ @param [in] pName Address of a zero terminated name string
+ @param [in] pGuid Address of the GUID to display
+
+ @retval EFI_SUCCESS The request was successfully processed
+
+**/
+EFI_STATUS
+RowGuid (
+ IN int SocketFD,
+ IN WSDT_PORT * pPort,
+ IN CONST CHAR8 * pName,
+ IN CONST EFI_GUID * pGuid
+ );
+
+/**
+ Display a row containing a hex value
+
+ @param [in] SocketFD The socket's file descriptor to add to the list.
+ @param [in] pPort The WSDT_PORT structure address
+ @param [in] pName Address of a zero terminated name string
+ @param [in] Value The value to display
+ @param [in] pWebPage Address of a zero terminated web page name
+
+ @retval EFI_SUCCESS The request was successfully processed
+
+**/
+EFI_STATUS
+RowHexValue (
+ IN int SocketFD,
+ IN WSDT_PORT * pPort,
+ IN CONST CHAR8 * pName,
+ IN UINT64 Value,
+ IN CONST CHAR16 * pWebPage
+ );
+
+/**
+ Display a row containing a pointer
+
+ @param [in] SocketFD The socket's file descriptor to add to the list.
+ @param [in] pPort The WSDT_PORT structure address
+ @param [in] pName Address of a zero terminated name string
+ @param [in] pAddress The address to display
+ @param [in] pWebPage Address of a zero terminated web page name
+
+ @retval EFI_SUCCESS The request was successfully processed
+
+**/
+EFI_STATUS
+RowPointer (
+ IN int SocketFD,
+ IN WSDT_PORT * pPort,
+ IN CONST CHAR8 * pName,
+ IN CONST VOID * pAddress,
+ IN CONST CHAR16 * pWebPage
+ );
+
+/**
+ Display a row containing a revision
+
+ @param [in] SocketFD The socket's file descriptor to add to the list.
+ @param [in] pPort The WSDT_PORT structure address
+ @param [in] pName Address of a zero terminated name string
+ @param [in] Revision The revision to display
+
+ @retval EFI_SUCCESS The request was successfully processed
+
+**/
+EFI_STATUS
+RowRevision (
+ IN int SocketFD,
+ IN WSDT_PORT * pPort,
+ IN CONST CHAR8 * pName,
+ IN UINT32 Revision
+ );
+
+/**
+ Display a row containing a unicode string
+
+ @param [in] SocketFD The socket's file descriptor to add to the list.
+ @param [in] pPort The WSDT_PORT structure address
+ @param [in] pName Address of a zero terminated name string
+ @param [in] pString Address of a zero terminated unicode string
+
+ @retval EFI_SUCCESS The request was successfully processed
+
+**/
+EFI_STATUS
+RowUnicodeString (
+ IN int SocketFD,
+ IN WSDT_PORT * pPort,
+ IN CONST CHAR8 * pName,
+ IN CONST CHAR16 * pString
+ );
+
+/**
+ Start the table page
+
+ @param [in] SocketFD The socket's file descriptor to add to the list.
+ @param [in] pPort The WSDT_PORT structure address
+ @param [in] pName Address of a zero terminated name string
+ @param [in] pTable Address of the table
+
+ @retval EFI_SUCCESS The request was successfully processed
+
+**/
+EFI_STATUS
+TableHeader (
+ IN int SocketFD,
+ IN WSDT_PORT * pPort,
+ IN CONST CHAR16 * pName,
+ IN CONST VOID * pTable
+ );
+
+/**
+ End the table 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
+TableTrailer (
+ IN int SocketFD,
+ IN WSDT_PORT * pPort,
+ OUT BOOLEAN *pbDone
+ );
+
+/**
+ HTTP port creation timer routine
+
+ This routine polls the socket layer waiting for the initial network connection
+ which will enable the creation of the HTTP port. The socket layer will manage
+ the coming and going of the network connections after that until the last network
+ connection is broken.
+
+ @param [in] pWebServer The web server control structure address.
+
+**/
+VOID
+WebServerTimer (
+ IN DT_WEB_SERVER * pWebServer
+ );
+
+/**
+ 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
+ );
+
+/**
+ 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
+ );
+
+//------------------------------------------------------------------------------
+// Driver Binding Protocol Support
+//------------------------------------------------------------------------------
+
+/**
+ Stop this driver on Controller by removing NetworkInterfaceIdentifier protocol and
+ closing the DevicePath and PciIo protocols on Controller.
+
+ @param [in] pThis Protocol instance pointer.
+ @param [in] Controller Handle of device to stop driver on.
+ @param [in] NumberOfChildren How many children need to be stopped.
+ @param [in] pChildHandleBuffer Not used.
+
+ @retval EFI_SUCCESS This driver is removed Controller.
+ @retval EFI_DEVICE_ERROR The device could not be stopped due to a device error.
+ @retval other This driver was not removed from this device.
+
+**/
+EFI_STATUS
+EFIAPI
+DriverStop (
+ IN EFI_DRIVER_BINDING_PROTOCOL * pThis,
+ IN EFI_HANDLE Controller,
+ IN UINTN NumberOfChildren,
+ IN EFI_HANDLE * pChildHandleBuffer
+ );
+
+//------------------------------------------------------------------------------
+// EFI Component Name Protocol Support
+//------------------------------------------------------------------------------
+
+/**
+ Retrieves a Unicode string that is the user readable name of the driver.
+
+ This function retrieves the user readable name of a driver in the form of a
+ Unicode string. If the driver specified by This has a user readable name in
+ the language specified by Language, then a pointer to the driver name is
+ returned in DriverName, and EFI_SUCCESS is returned. If the driver specified
+ by This does not support the language specified by Language,
+ then EFI_UNSUPPORTED is returned.
+
+ @param [in] pThis A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
+ EFI_COMPONENT_NAME_PROTOCOL instance.
+ @param [in] pLanguage A pointer to a Null-terminated ASCII string
+ array indicating the language. This is the
+ language of the driver name that the caller is
+ requesting, and it must match one of the
+ languages specified in SupportedLanguages. The
+ number of languages supported by a driver is up
+ to the driver writer. Language is specified
+ in RFC 3066 or ISO 639-2 language code format.
+ @param [out] ppDriverName A pointer to the Unicode string to return.
+ This Unicode string is the name of the
+ driver specified by This in the language
+ specified by Language.
+
+ @retval EFI_SUCCESS The Unicode string for the Driver specified by
+ This and the language specified by Language was
+ returned in DriverName.
+ @retval EFI_INVALID_PARAMETER Language is NULL.
+ @retval EFI_INVALID_PARAMETER DriverName is NULL.
+ @retval EFI_UNSUPPORTED The driver specified by This does not support
+ the language specified by Language.
+
+**/
+EFI_STATUS
+EFIAPI
+GetDriverName (
+ IN EFI_COMPONENT_NAME_PROTOCOL * pThis,
+ IN CHAR8 * pLanguage,
+ OUT CHAR16 ** ppDriverName
+ );
+
+
+/**
+ Retrieves a Unicode string that is the user readable name of the controller
+ that is being managed by a driver.
+
+ This function retrieves the user readable name of the controller specified by
+ ControllerHandle and ChildHandle in the form of a Unicode string. If the
+ driver specified by This has a user readable name in the language specified by
+ Language, then a pointer to the controller name is returned in ControllerName,
+ and EFI_SUCCESS is returned. If the driver specified by This is not currently
+ managing the controller specified by ControllerHandle and ChildHandle,
+ then EFI_UNSUPPORTED is returned. If the driver specified by This does not
+ support the language specified by Language, then EFI_UNSUPPORTED is returned.
+
+ @param [in] pThis A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
+ EFI_COMPONENT_NAME_PROTOCOL instance.
+ @param [in] ControllerHandle The handle of a controller that the driver
+ specified by This is managing. This handle
+ specifies the controller whose name is to be
+ returned.
+ @param [in] ChildHandle The handle of the child controller to retrieve
+ the name of. This is an optional parameter that
+ may be NULL. It will be NULL for device
+ drivers. It will also be NULL for a bus drivers
+ that wish to retrieve the name of the bus
+ controller. It will not be NULL for a bus
+ driver that wishes to retrieve the name of a
+ child controller.
+ @param [in] pLanguage A pointer to a Null-terminated ASCII string
+ array indicating the language. This is the
+ language of the driver name that the caller is
+ requesting, and it must match one of the
+ languages specified in SupportedLanguages. The
+ number of languages supported by a driver is up
+ to the driver writer. Language is specified in
+ RFC 3066 or ISO 639-2 language code format.
+ @param [out] ppControllerName A pointer to the Unicode string to return.
+ This Unicode string is the name of the
+ controller specified by ControllerHandle and
+ ChildHandle in the language specified by
+ Language from the point of view of the driver
+ specified by This.
+
+ @retval EFI_SUCCESS The Unicode string for the user readable name in
+ the language specified by Language for the
+ driver specified by This was returned in
+ DriverName.
+ @retval EFI_INVALID_PARAMETER ControllerHandle is not a valid EFI_HANDLE.
+ @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid
+ EFI_HANDLE.
+ @retval EFI_INVALID_PARAMETER Language is NULL.
+ @retval EFI_INVALID_PARAMETER ControllerName is NULL.
+ @retval EFI_UNSUPPORTED The driver specified by This is not currently
+ managing the controller specified by
+ ControllerHandle and ChildHandle.
+ @retval EFI_UNSUPPORTED The driver specified by This does not support
+ the language specified by Language.
+
+**/
+EFI_STATUS
+EFIAPI
+GetControllerName (
+ IN EFI_COMPONENT_NAME_PROTOCOL * pThis,
+ IN EFI_HANDLE ControllerHandle,
+ IN OPTIONAL EFI_HANDLE ChildHandle,
+ IN CHAR8 * pLanguage,
+ OUT CHAR16 ** ppControllerName
+ );
+
+//------------------------------------------------------------------------------
+
+#endif // _WEB_SERVER_H_
diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/WebServer/WebServer.inf b/uefi/linaro-edk2/AppPkg/Applications/Sockets/WebServer/WebServer.inf
new file mode 100644
index 0000000..27faefb
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/WebServer/WebServer.inf
@@ -0,0 +1,113 @@
+## @file
+# Web Server Application
+#
+# Copyright (c) 2011-2012, Intel Corporation
+# All rights reserved. This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = WebServer
+ FILE_GUID = 99E87DCF-6162-40c5-9FA1-32111F5197F7
+ MODULE_TYPE = UEFI_APPLICATION
+ VERSION_STRING = 1.0
+ ENTRY_POINT = ShellCEntryLib
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF EBC
+#
+
+[Sources]
+ ACPI.c
+ BootServicesTable.c
+ ConfigurationTable.c
+ DhcpOptions.c
+ DxeServicesTable.c
+ Exit.c
+ Firmware.c
+ Handles.c
+ Hello.c
+ HTTP.c
+ Index.c
+ MemoryMap.c
+ PageList.c
+ Ports.c
+ Reboot.c
+ RuntimeServicesTable.c
+ SystemTable.c
+ WebServer.c
+
+[Sources.IA32]
+ Mtrr.c
+
+[Sources.X64]
+ Mtrr.c
+
+
+[Pcd]
+ gAppPkgTokenSpaceGuid.WebServer_HttpPort
+
+[Packages]
+ AppPkg/AppPkg.dec
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ ShellPkg/ShellPkg.dec
+ StdLib/StdLib.dec
+
+[Packages.IA32]
+ UefiCpuPkg/UefiCpuPkg.dec
+
+[Packages.X64]
+ UefiCpuPkg/UefiCpuPkg.dec
+
+
+[LibraryClasses]
+ BaseMemoryLib
+ BsdSocketLib
+ DebugLib
+ DevMedia
+ DxeServicesTableLib
+ EfiSocketLib
+ LibC
+ ShellLib
+ ShellCEntryLib
+ UefiBootServicesTableLib
+ UefiLib
+ UefiRuntimeServicesTableLib
+# UseSocketDxe
+
+[LibraryClasses.IA32]
+ MtrrLib
+
+[LibraryClasses.X64]
+ MtrrLib
+
+
+[Guids]
+ gEfiAcpi10TableGuid
+ gEfiAcpiTableGuid
+ gEfiDebugImageInfoTableGuid
+ gEfiDxeServicesTableGuid
+ gEfiHobListGuid
+ gEfiMemoryTypeInformationGuid
+ gLoadFixedAddressConfigurationTableGuid
+
+[Protocols]
+ gEfiDhcp4ServiceBindingProtocolGuid # PROTOCOL ALWAYS_CONSUMED
+ gEfiDhcp4ProtocolGuid # PROTOCOL ALWAYS_CONSUMED
+
+[BuildOptions]
+ INTEL:*_*_*_CC_FLAGS = /Qdiag-disable:181,186
+ MSFT:*_*_*_CC_FLAGS = /Od
+ GCC:*_*_*_CC_FLAGS = -O0 -Wno-unused-variable
+