--- /dev/null
+/** @file\r
+ Definitions for the TFTP server.\r
+\r
+ Copyright (c) 2011, Intel Corporation\r
+ All rights reserved. This program and the accompanying materials\r
+ are licensed and made available under the terms and conditions of the BSD License\r
+ which accompanies this distribution. The full text of the license may be found at\r
+ http://opensource.org/licenses/bsd-license.php\r
+\r
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#ifndef _TFTP_SERVER_H_\r
+#define _TFTP_SERVER_H_\r
+\r
+#include <errno.h>\r
+#include <stdlib.h>\r
+#include <string.h>\r
+#include <Uefi.h>\r
+\r
+#include <Guid/EventGroup.h>\r
+\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/PcdLib.h>\r
+#include <Library/UefiApplicationEntryPoint.h>\r
+#include <Library/UefiBootServicesTableLib.h>\r
+#include <Library/UefiLib.h>\r
+#include <Protocol/BlockIo.h>\r
+\r
+#include <netinet/in.h>\r
+\r
+#include <sys/EfiSysCall.h>\r
+#include <sys/poll.h>\r
+#include <sys/socket.h>\r
+\r
+//------------------------------------------------------------------------------\r
+// Macros\r
+//------------------------------------------------------------------------------\r
+\r
+#if defined(_MSC_VER) /* Handle Microsoft VC++ compiler specifics. */\r
+#define DBG_ENTER() DEBUG (( DEBUG_INFO, "Entering " __FUNCTION__ "\n" )) ///< Display routine entry\r
+#define DBG_EXIT() DEBUG (( DEBUG_INFO, "Exiting " __FUNCTION__ "\n" )) ///< Display routine exit\r
+#define DBG_EXIT_DEC(Status) DEBUG (( DEBUG_INFO, "Exiting " __FUNCTION__ ", Status: %d\n", Status )) ///< Display routine exit with decimal value\r
+#define DBG_EXIT_HEX(Status) DEBUG (( DEBUG_INFO, "Exiting " __FUNCTION__ ", Status: 0x%08x\n", Status )) ///< Display routine exit with hex value\r
+#define DBG_EXIT_STATUS(Status) DEBUG (( DEBUG_INFO, "Exiting " __FUNCTION__ ", Status: %r\n", Status )) ///< Display routine exit with status value\r
+#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\r
+#else // _MSC_VER\r
+#define DBG_ENTER()\r
+#define DBG_EXIT()\r
+#define DBG_EXIT_DEC(Status)\r
+#define DBG_EXIT_HEX(Status)\r
+#define DBG_EXIT_STATUS(Status)\r
+#define DBG_EXIT_TF(Status)\r
+#endif // _MSC_VER\r
+\r
+#define DIM(x) ( sizeof ( x ) / sizeof ( x[0] )) ///< Compute the number of entries in an array\r
+\r
+//------------------------------------------------------------------------------\r
+// Constants\r
+//------------------------------------------------------------------------------\r
+\r
+#define DEBUG_SOCKET_POLL 0x40000000 ///< Display the socket poll messages\r
+#define DEBUG_PORT_WORK 0x20000000 ///< Display the port work messages\r
+#define DEBUG_SERVER_TIMER 0x10000000 ///< Display the socket poll messages\r
+#define DEBUG_TFTP_PORT 0x08000000 ///< Display the TFTP port messages\r
+#define DEBUG_TFTP_REQUEST 0x04000000 ///< Display the TFTP request messages\r
+#define DEBUG_TX 0x02000000 ///< Display transmit messages\r
+#define DEBUG_RX 0x01000000 ///< Display receive messages\r
+#define DEBUG_TFTP_ACK 0x00800000 ///< Display the TFTP ACK messages\r
+\r
+#define TFTP_PORT_POLL_DELAY ( 2 * 1000 ) ///< Delay in milliseconds for attempts to open the TFTP port\r
+#define CLIENT_POLL_DELAY 50 ///< Delay in milliseconds between client polls\r
+\r
+#define TPL_TFTP_SERVER TPL_CALLBACK ///< TPL for routine synchronization\r
+\r
+/**\r
+ Verify new TPL value\r
+\r
+ This macro which is enabled when debug is enabled verifies that\r
+ the new TPL value is >= the current TPL value.\r
+**/\r
+#ifdef VERIFY_TPL\r
+#undef VERIFY_TPL\r
+#endif // VERIFY_TPL\r
+\r
+#if !defined(MDEPKG_NDEBUG)\r
+\r
+#define VERIFY_TPL(tpl) \\r
+{ \\r
+ EFI_TPL PreviousTpl; \\r
+ \\r
+ PreviousTpl = gBS->RaiseTPL ( TPL_HIGH_LEVEL ); \\r
+ gBS->RestoreTPL ( PreviousTpl ); \\r
+ if ( PreviousTpl > tpl ) { \\r
+ DEBUG (( DEBUG_ERROR, "Current TPL: %d, New TPL: %d\r\n", PreviousTpl, tpl )); \\r
+ ASSERT ( PreviousTpl <= tpl ); \\r
+ } \\r
+}\r
+\r
+#else // MDEPKG_NDEBUG\r
+\r
+#define VERIFY_TPL(tpl)\r
+\r
+#endif // MDEPKG_NDEBUG\r
+\r
+#define TFTP_SERVER_SIGNATURE SIGNATURE_32('T','F','T','P') ///< TSDT_TFTP_SERVER memory signature\r
+\r
+//\r
+// See: http://www.rfc-editor.org/rfc/pdfrfc/rfc1350.txt.pdf\r
+//\r
+// TFTP Operations\r
+//\r
+\r
+#define TFTP_OP_READ_REQUEST 1 ///< Read request, zero terminated file name, zero terminated mode\r
+#define TFTP_OP_WRITE_REQUEST 2 ///< Write request, zero terminated file name, zero terminated mode\r
+#define TFTP_OP_DATA 3 ///< Data block, end-of-file indicated by short block\r
+#define TFTP_OP_ACK 4 ///< ACK block number\r
+#define TFTP_OP_ERROR 5 ///< Error number and explaination\r
+#define TFTP_OP_OACK 6 ///< ACK the options\r
+\r
+#define TFTP_MAX_BLOCK_SIZE 4096 ///< Maximum block size\r
+\r
+//------------------------------------------------------------------------------\r
+// Data Types\r
+//------------------------------------------------------------------------------\r
+\r
+/**\r
+ Port control structure\r
+**/\r
+typedef struct _TSDT_CONNECTION_CONTEXT TSDT_CONNECTION_CONTEXT;\r
+typedef struct _TSDT_CONNECTION_CONTEXT {\r
+ //\r
+ // Remote connection management\r
+ //\r
+ TSDT_CONNECTION_CONTEXT * pNext; ///< Next context in the connection list\r
+ struct sockaddr_in RemoteAddress; ///< Remote address\r
+\r
+ //\r
+ // TFTP management parameters\r
+ //\r
+ UINT16 AckNext; ///< Next block to be received\r
+ BOOLEAN bExpectAck; ///< TRUE for read, FALSE for write\r
+ UINT32 BlockSize; ///< Negotiated block size\r
+ UINT32 Timeout; ///< Number of seconds to wait before retransmission\r
+\r
+ //\r
+ // File management parameters\r
+ //\r
+ EFI_HANDLE File; ///< NULL while file is closed\r
+ UINT64 LengthInBytes; ///< Size of the file\r
+ UINT64 MaxTransferSize; ///< Maximum transfer size\r
+ BOOLEAN bEofSent; ///< End of file sent\r
+ UINT8 * pBuffer; ///< Pointer into the file data\r
+ UINT8 * pEnd; ///< End of the file data\r
+ UINT8 FileData [ 64 * TFTP_MAX_BLOCK_SIZE ]; ///< File data to send\r
+\r
+ //\r
+ // Buffer management\r
+ //\r
+ ssize_t TxBytes; ///< Bytes in the TX buffer\r
+ UINT8 TxBuffer [ 2 + 2 + TFTP_MAX_BLOCK_SIZE ]; ///< Transmit buffer\r
+}GCC_TSDT_CONNECTION_CONTEXT;\r
+\r
+/**\r
+ TFTP server control structure\r
+**/\r
+typedef struct {\r
+ UINTN Signature; ///< Structure identification\r
+\r
+ //\r
+ // Image attributes\r
+ //\r
+ EFI_HANDLE ImageHandle; ///< Image handle\r
+\r
+ //\r
+ // TFTP port management\r
+ //\r
+ BOOLEAN bTimerRunning; ///< Port creation timer status\r
+ EFI_EVENT TimerEvent; ///< Timer to open TFTP port\r
+ struct pollfd TftpPort; ///< Poll descriptor for the TFTP port\r
+ struct sockaddr_in TftpServerAddress; ///< Address of the local TFTP server\r
+\r
+ //\r
+ // Request management\r
+ //\r
+ struct sockaddr_in RemoteAddress; ///< Remote address\r
+ ssize_t RxBytes; ///< Receive data length in bytes\r
+ UINT8 RxBuffer [ 2 + 2 + TFTP_MAX_BLOCK_SIZE ]; ///< Receive buffer\r
+\r
+ //\r
+ // Client port management\r
+ //\r
+ TSDT_CONNECTION_CONTEXT * pContextList; ///< List of connection context structures\r
+} TSDT_TFTP_SERVER;\r
+\r
+//#define SERVER_FROM_SERVICE(a) CR(a, TSDT_TFTP_SERVER, ServiceBinding, TFTP_SERVER_SIGNATURE) ///< Locate DT_LAYER from service binding\r
+\r
+extern TSDT_TFTP_SERVER mTftpServer;\r
+\r
+//------------------------------------------------------------------------------\r
+// Support routines\r
+//------------------------------------------------------------------------------\r
+\r
+/**\r
+ Process the TFTP request\r
+\r
+ @param [in] pOption Address of the first zero terminated option string\r
+ @param [in] pValue Address to receive the value\r
+\r
+ @retval EFI_SUCCESS Option translated into a value\r
+\r
+**/\r
+EFI_STATUS\r
+TftpOptionValue (\r
+ IN UINT8 * pOption,\r
+ IN INT32 * pValue\r
+ );\r
+\r
+/**\r
+ Process the TFTP request\r
+\r
+ @param [in] pTftpServer The TFTP server control structure address.\r
+ @param [in] pContext Connection context structure address\r
+\r
+**/\r
+VOID\r
+TftpProcessRequest (\r
+ IN TSDT_TFTP_SERVER * pTftpServer,\r
+ IN TSDT_CONNECTION_CONTEXT * pContext\r
+ );\r
+\r
+/**\r
+ Build and send an error packet\r
+\r
+ @param [in] pTftpServer The TFTP server control structure address.\r
+ @param [in] pContext The context structure address.\r
+ @param [in] Error Error number for the packet\r
+ @param [in] pError Zero terminated error string address\r
+\r
+ @retval EFI_SUCCESS Message processed successfully\r
+\r
+**/\r
+EFI_STATUS\r
+TftpSendError (\r
+ IN TSDT_TFTP_SERVER * pTftpServer,\r
+ IN TSDT_CONNECTION_CONTEXT * pContext,\r
+ IN UINT16 Error,\r
+ IN UINT8 * pError\r
+ );\r
+\r
+/**\r
+ Send the next block of file system data\r
+\r
+ @param [in] pTftpServer The TFTP server control structure address.\r
+ @param [in] pContext The context structure address.\r
+\r
+ @retval EFI_SUCCESS Message processed successfully\r
+\r
+**/\r
+EFI_STATUS\r
+TftpSendNextBlock (\r
+ IN TSDT_TFTP_SERVER * pTftpServer,\r
+ IN TSDT_CONNECTION_CONTEXT * pContext\r
+ );\r
+\r
+/**\r
+ TFTP port creation timer routine\r
+\r
+ This routine polls the socket layer waiting for the initial network connection\r
+ which will enable the creation of the TFTP port. The socket layer will manage\r
+ the coming and going of the network connections after that until the last network\r
+ connection is broken.\r
+\r
+ @param [in] pTftpServer The TFTP server control structure address.\r
+\r
+**/\r
+VOID\r
+TftpServerTimer (\r
+ IN TSDT_TFTP_SERVER * pTftpServer\r
+ );\r
+\r
+/**\r
+ Start the TFTP server port creation timer\r
+\r
+ @param [in] pTftpServer The TFTP server control structure address.\r
+\r
+ @retval EFI_SUCCESS The timer was successfully started.\r
+ @retval EFI_ALREADY_STARTED The timer is already running.\r
+ @retval Other The timer failed to start.\r
+\r
+**/\r
+EFI_STATUS\r
+TftpServerTimerStart (\r
+ IN TSDT_TFTP_SERVER * pTftpServer\r
+ );\r
+\r
+/**\r
+ Stop the TFTP server port creation timer\r
+\r
+ @param [in] pTftpServer The TFTP server control structure address.\r
+\r
+ @retval EFI_SUCCESS The TFTP port timer is stopped\r
+ @retval Other Failed to stop the TFTP port timer\r
+\r
+**/\r
+EFI_STATUS\r
+TftpServerTimerStop (\r
+ IN TSDT_TFTP_SERVER * pTftpServer\r
+ );\r
+\r
+/**\r
+ Send the next TFTP packet\r
+\r
+ @param [in] pTftpServer The TFTP server control structure address.\r
+ @param [in] pContext The context structure address.\r
+\r
+ @retval EFI_SUCCESS Message processed successfully\r
+\r
+**/\r
+EFI_STATUS\r
+TftpTxPacket (\r
+ IN TSDT_TFTP_SERVER * pTftpServer,\r
+ IN TSDT_CONNECTION_CONTEXT * pContext\r
+ );\r
+\r
+//------------------------------------------------------------------------------\r
+\r
+#endif // _TFTP_SERVER_H_\r