b1e9f83ce59995d1f99080d9f5d2242d16e65dfb
[mirror_edk2.git] / AppPkg / Applications / Sockets / TftpServer / TftpServer.h
1 /** @file
2 Definitions for the TFTP server.
3
4 Copyright (c) 2011, Intel Corporation
5 All rights reserved. This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
9
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12
13 **/
14
15 #ifndef _TFTP_SERVER_H_
16 #define _TFTP_SERVER_H_
17
18 #include <errno.h>
19 #include <stdlib.h>
20 #include <string.h>
21 #include <Uefi.h>
22
23 #include <Guid/EventGroup.h>
24
25 #include <Library/BaseMemoryLib.h>
26 #include <Library/DebugLib.h>
27 #include <Library/PcdLib.h>
28 #include <Library/UefiApplicationEntryPoint.h>
29 #include <Library/UefiBootServicesTableLib.h>
30 #include <Library/UefiLib.h>
31 #include <Protocol/BlockIo.h>
32
33 #include <netinet/in.h>
34
35 #include <sys/EfiSysCall.h>
36 #include <sys/poll.h>
37 #include <sys/socket.h>
38
39 //------------------------------------------------------------------------------
40 // Macros
41 //------------------------------------------------------------------------------
42
43 #if defined(_MSC_VER) /* Handle Microsoft VC++ compiler specifics. */
44 #define DBG_ENTER() DEBUG (( DEBUG_INFO, "Entering " __FUNCTION__ "\n" )) ///< Display routine entry
45 #define DBG_EXIT() DEBUG (( DEBUG_INFO, "Exiting " __FUNCTION__ "\n" )) ///< Display routine exit
46 #define DBG_EXIT_DEC(Status) DEBUG (( DEBUG_INFO, "Exiting " __FUNCTION__ ", Status: %d\n", Status )) ///< Display routine exit with decimal value
47 #define DBG_EXIT_HEX(Status) DEBUG (( DEBUG_INFO, "Exiting " __FUNCTION__ ", Status: 0x%08x\n", Status )) ///< Display routine exit with hex value
48 #define DBG_EXIT_STATUS(Status) DEBUG (( DEBUG_INFO, "Exiting " __FUNCTION__ ", Status: %r\n", Status )) ///< Display routine exit with status value
49 #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
50 #else // _MSC_VER
51 #define DBG_ENTER()
52 #define DBG_EXIT()
53 #define DBG_EXIT_DEC(Status)
54 #define DBG_EXIT_HEX(Status)
55 #define DBG_EXIT_STATUS(Status)
56 #define DBG_EXIT_TF(Status)
57 #endif // _MSC_VER
58
59 #define DIM(x) ( sizeof ( x ) / sizeof ( x[0] )) ///< Compute the number of entries in an array
60
61 //------------------------------------------------------------------------------
62 // Constants
63 //------------------------------------------------------------------------------
64
65 #define DEBUG_PORT_WORK 0x40000000 ///< Display the port work messages
66 #define DEBUG_SERVER_TIMER 0x20000000 ///< Display the socket poll messages
67 #define DEBUG_TFTP_PORT 0x10000000 ///< Display the TFTP port messages
68 #define DEBUG_TFTP_REQUEST 0x08000000 ///< Display the TFTP request messages
69 #define DEBUG_TX 0x04000000 ///< Display transmit messages
70 #define DEBUG_SOCKET_POLL 0x02000000 ///< Display the socket poll messages
71 #define DEBUG_RX 0x01000000 ///< Display receive messages
72 #define DEBUG_TFTP_ACK 0x00800000 ///< Display the TFTP ACK messages
73
74 #define TFTP_PORT_POLL_DELAY ( 2 * 1000 ) ///< Delay in milliseconds for attempts to open the TFTP port
75 #define CLIENT_POLL_DELAY 50 ///< Delay in milliseconds between client polls
76
77 #define TPL_TFTP_SERVER TPL_CALLBACK ///< TPL for routine synchronization
78
79 /**
80 Verify new TPL value
81
82 This macro which is enabled when debug is enabled verifies that
83 the new TPL value is >= the current TPL value.
84 **/
85 #ifdef VERIFY_TPL
86 #undef VERIFY_TPL
87 #endif // VERIFY_TPL
88
89 #if !defined(MDEPKG_NDEBUG)
90
91 #define VERIFY_TPL(tpl) \
92 { \
93 EFI_TPL PreviousTpl; \
94 \
95 PreviousTpl = gBS->RaiseTPL ( TPL_HIGH_LEVEL ); \
96 gBS->RestoreTPL ( PreviousTpl ); \
97 if ( PreviousTpl > tpl ) { \
98 DEBUG (( DEBUG_ERROR, "Current TPL: %d, New TPL: %d\r\n", PreviousTpl, tpl )); \
99 ASSERT ( PreviousTpl <= tpl ); \
100 } \
101 }
102
103 #else // MDEPKG_NDEBUG
104
105 #define VERIFY_TPL(tpl)
106
107 #endif // MDEPKG_NDEBUG
108
109 #define TFTP_SERVER_SIGNATURE SIGNATURE_32('T','F','T','P') ///< TSDT_TFTP_SERVER memory signature
110
111 //
112 // See: http://www.rfc-editor.org/rfc/pdfrfc/rfc1350.txt.pdf
113 //
114 // TFTP Operations
115 //
116
117 #define TFTP_OP_READ_REQUEST 1 ///< Read request, zero terminated file name, zero terminated mode
118 #define TFTP_OP_WRITE_REQUEST 2 ///< Write request, zero terminated file name, zero terminated mode
119 #define TFTP_OP_DATA 3 ///< Data block, end-of-file indicated by short block
120 #define TFTP_OP_ACK 4 ///< ACK block number
121 #define TFTP_OP_ERROR 5 ///< Error number and explaination
122 #define TFTP_OP_OACK 6 ///< ACK the options
123
124 #define TFTP_MAX_BLOCK_SIZE 4096 ///< Maximum block size
125
126 //------------------------------------------------------------------------------
127 // Data Types
128 //------------------------------------------------------------------------------
129
130 /**
131 Port control structure
132 **/
133 typedef struct _TSDT_CONNECTION_CONTEXT TSDT_CONNECTION_CONTEXT;
134 typedef struct _TSDT_CONNECTION_CONTEXT {
135 //
136 // Remote connection management
137 //
138 TSDT_CONNECTION_CONTEXT * pNext; ///< Next context in the connection list
139 struct sockaddr_in RemoteAddress; ///< Remote address
140
141 //
142 // TFTP management parameters
143 //
144 UINT16 AckNext; ///< Next block to be received
145 BOOLEAN bExpectAck; ///< TRUE for read, FALSE for write
146 UINT32 BlockSize; ///< Negotiated block size
147 UINT32 Timeout; ///< Number of seconds to wait before retransmission
148
149 //
150 // File management parameters
151 //
152 EFI_HANDLE File; ///< NULL while file is closed
153 UINT64 LengthInBytes; ///< Size of the file
154 UINT64 MaxTransferSize; ///< Maximum transfer size
155 BOOLEAN bEofSent; ///< End of file sent
156 UINT8 * pBuffer; ///< Pointer into the file data
157 UINT8 * pEnd; ///< End of the file data
158 UINT8 FileData[ 64 * TFTP_MAX_BLOCK_SIZE ]; ///< File data to send
159
160 //
161 // Buffer management
162 //
163 ssize_t TxBytes; ///< Bytes in the TX buffer
164 UINT8 TxBuffer[ 2 + 2 + TFTP_MAX_BLOCK_SIZE ]; ///< Transmit buffer
165 }GCC_TSDT_CONNECTION_CONTEXT;
166
167 /**
168 TFTP server control structure
169 **/
170 typedef struct {
171 UINTN Signature; ///< Structure identification
172
173 //
174 // Image attributes
175 //
176 EFI_HANDLE ImageHandle; ///< Image handle
177
178 //
179 // TFTP port management
180 //
181 BOOLEAN bTimerRunning; ///< Port creation timer status
182 EFI_EVENT TimerEvent; ///< Timer to open TFTP port
183 struct pollfd TftpPort; ///< Poll descriptor for the TFTP port
184 struct sockaddr_in TftpServerAddress; ///< Address of the local TFTP server
185
186 //
187 // Request management
188 //
189 struct sockaddr_in RemoteAddress; ///< Remote address
190 ssize_t RxBytes; ///< Receive data length in bytes
191 UINT8 RxBuffer[ 2 + 2 + TFTP_MAX_BLOCK_SIZE ]; ///< Receive buffer
192
193 //
194 // Client port management
195 //
196 TSDT_CONNECTION_CONTEXT * pContextList; ///< List of connection context structures
197 } TSDT_TFTP_SERVER;
198
199 //#define SERVER_FROM_SERVICE(a) CR(a, TSDT_TFTP_SERVER, ServiceBinding, TFTP_SERVER_SIGNATURE) ///< Locate DT_LAYER from service binding
200
201 extern TSDT_TFTP_SERVER mTftpServer;
202
203 //------------------------------------------------------------------------------
204 // Support routines
205 //------------------------------------------------------------------------------
206
207 /**
208 Process the TFTP request
209
210 @param [in] pOption Address of the first zero terminated option string
211 @param [in] pValue Address to receive the value
212
213 @retval EFI_SUCCESS Option translated into a value
214
215 **/
216 EFI_STATUS
217 TftpOptionValue (
218 IN UINT8 * pOption,
219 IN INT32 * pValue
220 );
221
222 /**
223 Process the TFTP request
224
225 @param [in] pTftpServer The TFTP server control structure address.
226 @param [in] pContext Connection context structure address
227
228 **/
229 VOID
230 TftpProcessRequest (
231 IN TSDT_TFTP_SERVER * pTftpServer,
232 IN TSDT_CONNECTION_CONTEXT * pContext
233 );
234
235 /**
236 Build and send an error packet
237
238 @param [in] pTftpServer The TFTP server control structure address.
239 @param [in] pContext The context structure address.
240 @param [in] Error Error number for the packet
241 @param [in] pError Zero terminated error string address
242
243 @retval EFI_SUCCESS Message processed successfully
244
245 **/
246 EFI_STATUS
247 TftpSendError (
248 IN TSDT_TFTP_SERVER * pTftpServer,
249 IN TSDT_CONNECTION_CONTEXT * pContext,
250 IN UINT16 Error,
251 IN UINT8 * pError
252 );
253
254 /**
255 Send the next block of file system data
256
257 @param [in] pTftpServer The TFTP server control structure address.
258 @param [in] pContext The context structure address.
259
260 @retval EFI_SUCCESS Message processed successfully
261
262 **/
263 EFI_STATUS
264 TftpSendNextBlock (
265 IN TSDT_TFTP_SERVER * pTftpServer,
266 IN TSDT_CONNECTION_CONTEXT * pContext
267 );
268
269 /**
270 TFTP port creation timer routine
271
272 This routine polls the socket layer waiting for the initial network connection
273 which will enable the creation of the TFTP port. The socket layer will manage
274 the coming and going of the network connections after that until the last network
275 connection is broken.
276
277 @param [in] pTftpServer The TFTP server control structure address.
278
279 **/
280 VOID
281 TftpServerTimer (
282 IN TSDT_TFTP_SERVER * pTftpServer
283 );
284
285 /**
286 Start the TFTP server port creation timer
287
288 @param [in] pTftpServer The TFTP server control structure address.
289
290 @retval EFI_SUCCESS The timer was successfully started.
291 @retval EFI_ALREADY_STARTED The timer is already running.
292 @retval Other The timer failed to start.
293
294 **/
295 EFI_STATUS
296 TftpServerTimerStart (
297 IN TSDT_TFTP_SERVER * pTftpServer
298 );
299
300 /**
301 Stop the TFTP server port creation timer
302
303 @param [in] pTftpServer The TFTP server control structure address.
304
305 @retval EFI_SUCCESS The TFTP port timer is stopped
306 @retval Other Failed to stop the TFTP port timer
307
308 **/
309 EFI_STATUS
310 TftpServerTimerStop (
311 IN TSDT_TFTP_SERVER * pTftpServer
312 );
313
314 /**
315 Send the next TFTP packet
316
317 @param [in] pTftpServer The TFTP server control structure address.
318 @param [in] pContext The context structure address.
319
320 @retval EFI_SUCCESS Message processed successfully
321
322 **/
323 EFI_STATUS
324 TftpTxPacket (
325 IN TSDT_TFTP_SERVER * pTftpServer,
326 IN TSDT_CONNECTION_CONTEXT * pContext
327 );
328
329 //------------------------------------------------------------------------------
330
331 #endif // _TFTP_SERVER_H_