1 /** @file
2   The header files of miscellaneous routines for HttpDxe driver.
3 
4 Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
5 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 __EFI_HTTP_PROTO_H__
16 #define __EFI_HTTP_PROTO_H__
17 
18 #define DEF_BUF_LEN                         2048
19 
20 #define HTTP_SERVICE_SIGNATURE  SIGNATURE_32('H', 't', 't', 'S')
21 
22 #define HTTP_SERVICE_FROM_PROTOCOL(a) \
23   CR ( \
24   (a), \
25   HTTP_SERVICE, \
26   ServiceBinding, \
27   HTTP_SERVICE_SIGNATURE \
28   )
29 
30 
31 //
32 // The state of HTTP protocol. It starts from UNCONFIGED.
33 //
34 #define HTTP_STATE_UNCONFIGED        0
35 #define HTTP_STATE_HTTP_CONFIGED     1
36 #define HTTP_STATE_TCP_CONFIGED      2
37 #define HTTP_STATE_TCP_UNCONFIGED    3
38 #define HTTP_STATE_TCP_CONNECTED     4
39 #define HTTP_STATE_TCP_CLOSED        5
40 
41 //
42 // TCP configured data.
43 //
44 #define HTTP_TOS_DEAULT              8
45 #define HTTP_TTL_DEAULT              255
46 #define HTTP_BUFFER_SIZE_DEAULT      65535
47 #define HTTP_MAX_SYN_BACK_LOG        5
48 #define HTTP_CONNECTION_TIMEOUT      60
49 #define HTTP_DATA_RETRIES            12
50 #define HTTP_FIN_TIMEOUT             2
51 #define HTTP_KEEP_ALIVE_PROBES       6
52 #define HTTP_KEEP_ALIVE_TIME         7200
53 #define HTTP_KEEP_ALIVE_INTERVAL     30
54 
55 #define HTTP_URL_BUFFER_LEN          4096
56 
57 typedef struct _HTTP_SERVICE {
58   UINT32                        Signature;
59   EFI_SERVICE_BINDING_PROTOCOL  ServiceBinding;
60   EFI_HANDLE                    ImageHandle;
61   EFI_HANDLE                    ControllerHandle;
62   EFI_HANDLE                    Tcp4ChildHandle;
63   EFI_HANDLE                    Tcp6ChildHandle;
64   LIST_ENTRY                    ChildrenList;
65   UINTN                         ChildrenNumber;
66   INTN                          State;
67 } HTTP_SERVICE;
68 
69 typedef struct {
70   EFI_TCP4_IO_TOKEN             Tx4Token;
71   EFI_TCP4_TRANSMIT_DATA        Tx4Data;
72   EFI_TCP6_IO_TOKEN             Tx6Token;
73   EFI_TCP6_TRANSMIT_DATA        Tx6Data;
74   EFI_TCP4_IO_TOKEN             Rx4Token;
75   EFI_TCP4_RECEIVE_DATA         Rx4Data;
76   EFI_TCP6_IO_TOKEN             Rx6Token;
77   EFI_TCP6_RECEIVE_DATA         Rx6Data;
78   BOOLEAN                       IsTxDone;
79   BOOLEAN                       IsRxDone;
80   UINTN                         BodyLen;
81   EFI_HTTP_METHOD               Method;
82 } HTTP_TCP_TOKEN_WRAP;
83 
84 typedef struct _HTTP_PROTOCOL {
85   UINT32                        Signature;
86   EFI_HTTP_PROTOCOL             Http;
87   EFI_HANDLE                    Handle;
88   HTTP_SERVICE                  *Service;
89   LIST_ENTRY                    Link;   // Link to all HTTP instance from the service.
90   BOOLEAN                       InDestroy;
91   INTN                          State;
92 
93   EFI_HANDLE                    Tcp4ChildHandle;
94   EFI_TCP4_PROTOCOL             *Tcp4;
95   EFI_TCP4_CONFIG_DATA          Tcp4CfgData;
96   EFI_TCP4_OPTION               Tcp4Option;
97 
98   EFI_TCP4_CONNECTION_TOKEN     Tcp4ConnToken;
99   BOOLEAN                       IsTcp4ConnDone;
100   EFI_TCP4_CLOSE_TOKEN          Tcp4CloseToken;
101   BOOLEAN                       IsTcp4CloseDone;
102   CHAR8                         *RemoteHost;
103   UINT16                        RemotePort;
104   EFI_IPv4_ADDRESS              RemoteAddr;
105 
106   EFI_HANDLE                    Tcp6ChildHandle;
107   EFI_TCP6_PROTOCOL             *Tcp6;
108   EFI_TCP6_CONFIG_DATA          Tcp6CfgData;
109   EFI_TCP6_OPTION               Tcp6Option;
110 
111   EFI_TCP6_CONNECTION_TOKEN     Tcp6ConnToken;
112   BOOLEAN                       IsTcp6ConnDone;
113   EFI_TCP6_CLOSE_TOKEN          Tcp6CloseToken;
114   BOOLEAN                       IsTcp6CloseDone;
115   EFI_IPv6_ADDRESS              RemoteIpv6Addr;
116 
117 
118 
119   //
120   // Rx4Token or Rx6Token used for receiving HTTP header.
121   //
122   EFI_TCP4_IO_TOKEN             Rx4Token;
123   EFI_TCP4_RECEIVE_DATA         Rx4Data;
124   EFI_TCP6_IO_TOKEN             Rx6Token;
125   EFI_TCP6_RECEIVE_DATA         Rx6Data;
126   BOOLEAN                       IsRxDone;
127 
128   CHAR8                         **EndofHeader;
129   CHAR8                         **HttpHeaders;
130   CHAR8                         *CacheBody;
131   CHAR8                         *NextMsg;
132   UINTN                         CacheLen;
133   UINTN                         CacheOffset;
134 
135   //
136   // HTTP message-body parser.
137   //
138   VOID                          *MsgParser;
139 
140   EFI_HTTP_VERSION              HttpVersion;
141   UINT32                        TimeOutMillisec;
142   BOOLEAN                       LocalAddressIsIPv6;
143 
144   EFI_HTTPv4_ACCESS_POINT       IPv4Node;
145   EFI_HTTPv6_ACCESS_POINT       Ipv6Node;
146 
147   NET_MAP                       TxTokens;
148   NET_MAP                       RxTokens;
149 
150   CHAR8                         *Url;
151 } HTTP_PROTOCOL;
152 
153 typedef struct {
154   EFI_HTTP_TOKEN                *HttpToken;
155   HTTP_PROTOCOL                 *HttpInstance;
156   HTTP_TCP_TOKEN_WRAP           TcpWrap;
157 } HTTP_TOKEN_WRAP;
158 
159 
160 #define HTTP_PROTOCOL_SIGNATURE  SIGNATURE_32('H', 't', 't', 'P')
161 
162 #define HTTP_INSTANCE_FROM_PROTOCOL(a) \
163   CR ( \
164   (a), \
165   HTTP_PROTOCOL, \
166   Http, \
167   HTTP_PROTOCOL_SIGNATURE \
168   )
169 
170 /**
171   The common notify function used in HTTP driver.
172 
173   @param[in]  Event   The event signaled.
174   @param[in]  Context The context.
175 
176 **/
177 VOID
178 EFIAPI
179 HttpCommonNotify (
180   IN EFI_EVENT  Event,
181   IN VOID       *Context
182   );
183 
184 /**
185   Create events for the TCP connection token and TCP close token.
186 
187   @param[in]  HttpInstance       Pointer to HTTP_PROTOCOL structure.
188 
189   @retval EFI_SUCCESS            The events are created successfully.
190   @retval others                 Other error as indicated.
191 
192 **/
193 EFI_STATUS
194 HttpCreateTcpConnCloseEvent (
195   IN  HTTP_PROTOCOL        *HttpInstance
196   );
197 
198 /**
199   Close events in the TCP connection token and TCP close token.
200 
201   @param[in]  HttpInstance   Pointer to HTTP_PROTOCOL structure.
202 
203 **/
204 VOID
205 HttpCloseTcpConnCloseEvent (
206   IN  HTTP_PROTOCOL        *HttpInstance
207   );
208 
209 /**
210   Create event for the TCP transmit token.
211 
212   @param[in]  Wrap               Point to HTTP token's wrap data.
213 
214   @retval EFI_SUCCESS            The events is created successfully.
215   @retval others                 Other error as indicated.
216 
217 **/
218 EFI_STATUS
219 HttpCreateTcpTxEvent (
220   IN  HTTP_TOKEN_WRAP      *Wrap
221   );
222 
223 /**
224   Create event for the TCP receive token which is used to receive HTTP header.
225 
226   @param[in]  HttpInstance       Pointer to HTTP_PROTOCOL structure.
227 
228   @retval EFI_SUCCESS            The events is created successfully.
229   @retval others                 Other error as indicated.
230 
231 **/
232 EFI_STATUS
233 HttpCreateTcpRxEventForHeader (
234   IN  HTTP_PROTOCOL        *HttpInstance
235   );
236 
237 /**
238   Create event for the TCP receive token which is used to receive HTTP body.
239 
240   @param[in]  Wrap               Point to HTTP token's wrap data.
241 
242   @retval EFI_SUCCESS            The events is created successfully.
243   @retval others                 Other error as indicated.
244 
245 **/
246 EFI_STATUS
247 HttpCreateTcpRxEvent (
248   IN  HTTP_TOKEN_WRAP      *Wrap
249   );
250 
251 /**
252   Close Events for Tcp Receive Tokens for HTTP body and HTTP header.
253 
254   @param[in]  Wrap               Pointer to HTTP token's wrap data.
255 
256 **/
257 VOID
258 HttpCloseTcpRxEvent (
259   IN  HTTP_TOKEN_WRAP      *Wrap
260   );
261 
262 /**
263   Intiialize the HTTP_PROTOCOL structure to the unconfigured state.
264 
265   @param[in, out]  HttpInstance         Pointer to HTTP_PROTOCOL structure.
266   @param[in]       IpVersion            Indicate us TCP4 protocol or TCP6 protocol.
267 
268   @retval EFI_SUCCESS       HTTP_PROTOCOL structure is initialized successfully.
269   @retval Others            Other error as indicated.
270 
271 **/
272 EFI_STATUS
273 HttpInitProtocol (
274   IN OUT HTTP_PROTOCOL           *HttpInstance,
275   IN     BOOLEAN                 IpVersion
276   );
277 
278 /**
279   Clean up the HTTP child, release all the resources used by it.
280 
281   @param[in]  HttpInstance       The HTTP child to clean up.
282 
283 **/
284 VOID
285 HttpCleanProtocol (
286   IN  HTTP_PROTOCOL          *HttpInstance
287   );
288 
289 /**
290   Establish TCP connection with HTTP server.
291 
292   @param[in]  HttpInstance       The HTTP instance private data.
293 
294   @retval EFI_SUCCESS            The TCP connection is established.
295   @retval Others                 Other error as indicated.
296 
297 **/
298 EFI_STATUS
299 HttpCreateConnection (
300   IN  HTTP_PROTOCOL        *HttpInstance
301   );
302 
303 /**
304   Close existing TCP connection.
305 
306   @param[in]  HttpInstance       The HTTP instance private data.
307 
308   @retval EFI_SUCCESS            The TCP connection is closed.
309   @retval Others                 Other error as indicated.
310 
311 **/
312 EFI_STATUS
313 HttpCloseConnection (
314   IN  HTTP_PROTOCOL        *HttpInstance
315   );
316 
317 /**
318   Configure TCP4 protocol child.
319 
320   @param[in]  HttpInstance       The HTTP instance private data.
321   @param[in]  Wrap               The HTTP token's wrap data.
322 
323   @retval EFI_SUCCESS            The TCP4 protocol child is configured.
324   @retval Others                 Other error as indicated.
325 
326 **/
327 EFI_STATUS
328 HttpConfigureTcp4 (
329   IN  HTTP_PROTOCOL        *HttpInstance,
330   IN  HTTP_TOKEN_WRAP      *Wrap
331   );
332 
333 /**
334   Configure TCP6 protocol child.
335 
336   @param[in]  HttpInstance       The HTTP instance private data.
337   @param[in]  Wrap               The HTTP token's wrap data.
338 
339   @retval EFI_SUCCESS            The TCP6 protocol child is configured.
340   @retval Others                 Other error as indicated.
341 
342 **/
343 EFI_STATUS
344 HttpConfigureTcp6 (
345   IN  HTTP_PROTOCOL        *HttpInstance,
346   IN  HTTP_TOKEN_WRAP      *Wrap
347   );
348 
349 /**
350   Check existing TCP connection, if in error state, receover TCP4 connection.
351 
352   @param[in]  HttpInstance       The HTTP instance private data.
353 
354   @retval EFI_SUCCESS            The TCP connection is established.
355   @retval EFI_NOT_READY          TCP4 protocol child is not created or configured.
356   @retval Others                 Other error as indicated.
357 
358 **/
359 EFI_STATUS
360 HttpConnectTcp4 (
361   IN  HTTP_PROTOCOL        *HttpInstance
362   );
363 
364 /**
365   Check existing TCP connection, if in error state, recover TCP6 connection.
366 
367   @param[in]  HttpInstance       The HTTP instance private data.
368 
369   @retval EFI_SUCCESS            The TCP connection is established.
370   @retval EFI_NOT_READY          TCP6 protocol child is not created or configured.
371   @retval Others                 Other error as indicated.
372 
373 **/
374 EFI_STATUS
375 HttpConnectTcp6 (
376   IN  HTTP_PROTOCOL        *HttpInstance
377   );
378 
379 /**
380   Send the HTTP message through TCP4 or TCP6.
381 
382   @param[in]  HttpInstance       The HTTP instance private data.
383   @param[in]  Wrap               The HTTP token's wrap data.
384   @param[in]  TxString           Buffer containing the HTTP message string.
385   @param[in]  TxStringLen        Length of the HTTP message string in bytes.
386 
387   @retval EFI_SUCCESS            The HTTP message is queued into TCP transmit queue.
388   @retval Others                 Other error as indicated.
389 
390 **/
391 EFI_STATUS
392 HttpTransmitTcp (
393   IN  HTTP_PROTOCOL    *HttpInstance,
394   IN  HTTP_TOKEN_WRAP  *Wrap,
395   IN  UINT8            *TxString,
396   IN  UINTN            TxStringLen
397   );
398 
399 /**
400   Translate the status code in HTTP message to EFI_HTTP_STATUS_CODE defined
401   in UEFI 2.5 specification.
402 
403   @param[in]  StatusCode         The status code value in HTTP message.
404 
405   @return                        Value defined in EFI_HTTP_STATUS_CODE .
406 
407 **/
408 EFI_HTTP_STATUS_CODE
409 HttpMappingToStatusCode (
410   IN UINTN                  StatusCode
411   );
412 
413 /**
414   Check whether the user's token or event has already
415   been enqueue on HTTP Tx or Rx Token list.
416 
417   @param[in]  Map                The container of either user's transmit or receive
418                                  token.
419   @param[in]  Item               Current item to check against.
420   @param[in]  Context            The Token to check againist.
421 
422   @retval EFI_ACCESS_DENIED      The token or event has already been enqueued in IP
423   @retval EFI_SUCCESS            The current item isn't the same token/event as the
424                                  context.
425 
426 **/
427 EFI_STATUS
428 EFIAPI
429 HttpTokenExist (
430   IN NET_MAP                *Map,
431   IN NET_MAP_ITEM           *Item,
432   IN VOID                   *Context
433   );
434 
435 /**
436   Check whether the HTTP message associated with TxToken or Tx6Token is already sent out.
437 
438   @param[in]  Map                The container of TxToken.
439   @param[in]  Item               Current item to check against.
440   @param[in]  Context            The Token to check againist.
441 
442   @retval EFI_NOT_READY          The HTTP message is still queued in the list.
443   @retval EFI_SUCCESS            The HTTP message has been sent out.
444 
445 **/
446 EFI_STATUS
447 EFIAPI
448 HttpTcpNotReady (
449   IN NET_MAP                *Map,
450   IN NET_MAP_ITEM           *Item,
451   IN VOID                   *Context
452   );
453 
454 /**
455   Initialize TCP related data.
456 
457   @param[in]  HttpInstance       The HTTP instance private data.
458   @param[in]  Wrap               The HTTP token's wrap data.
459   @param[in]  Configure          The Flag indicates whether the first time to initialize Tcp.
460 
461   @retval EFI_SUCCESS            The initialization of TCP instance is done.
462   @retval Others                 Other error as indicated.
463 
464 **/
465 EFI_STATUS
466 HttpInitTcp (
467   IN  HTTP_PROTOCOL    *HttpInstance,
468   IN  HTTP_TOKEN_WRAP  *Wrap,
469   IN  BOOLEAN          Configure
470   );
471 
472 /**
473   Transmit the HTTP mssage by processing the associated HTTP token.
474 
475   @param[in]  Map                The container of TxToken or Tx6Token.
476   @param[in]  Item               Current item to check against.
477   @param[in]  Context            The Token to check againist.
478 
479   @retval EFI_OUT_OF_RESOURCES   Failed to allocate resources.
480   @retval EFI_SUCCESS            The HTTP message is queued into TCP transmit
481                                  queue.
482 
483 **/
484 EFI_STATUS
485 EFIAPI
486 HttpTcpTransmit (
487   IN NET_MAP                *Map,
488   IN NET_MAP_ITEM           *Item,
489   IN VOID                   *Context
490   );
491 
492 /**
493   Receive the HTTP response by processing the associated HTTP token.
494 
495   @param[in]  Map                The container of Rx4Token or Rx6Token.
496   @param[in]  Item               Current item to check against.
497   @param[in]  Context            The Token to check againist.
498 
499   @retval EFI_SUCCESS            The HTTP response is queued into TCP receive
500                                  queue.
501   @retval Others                 Other error as indicated.
502 
503 **/
504 EFI_STATUS
505 EFIAPI
506 HttpTcpReceive (
507   IN NET_MAP                *Map,
508   IN NET_MAP_ITEM           *Item,
509   IN VOID                   *Context
510   );
511 
512 /**
513   Receive the HTTP header by processing the associated HTTP token.
514 
515   @param[in]       HttpInstance    The HTTP instance private data.
516   @param[in, out]  SizeofHeaders   The HTTP header length.
517   @param[in, out]  BufferSize      The size of buffer to cacahe the header message.
518 
519   @retval EFI_SUCCESS              The HTTP header is received.
520   @retval Others                   Other errors as indicated.
521 
522 **/
523 EFI_STATUS
524 HttpTcpReceiveHeader (
525   IN  HTTP_PROTOCOL         *HttpInstance,
526   IN  OUT UINTN             *SizeofHeaders,
527   IN  OUT UINTN             *BufferSize
528   );
529 
530 /**
531   Receive the HTTP body by processing the associated HTTP token.
532 
533   @param[in]  Wrap               The HTTP token's wrap data.
534   @param[in]  HttpMsg            The HTTP message data.
535 
536   @retval EFI_SUCCESS            The HTTP body is received.
537   @retval Others                 Other error as indicated.
538 
539 **/
540 EFI_STATUS
541 HttpTcpReceiveBody (
542   IN  HTTP_TOKEN_WRAP       *Wrap,
543   IN  EFI_HTTP_MESSAGE      *HttpMsg
544   );
545 
546 /**
547   Clean up Tcp Tokens while the Tcp transmission error occurs.
548 
549   @param[in]  Wrap               Pointer to HTTP token's wrap data.
550 
551 **/
552 VOID
553 HttpTcpTokenCleanup (
554   IN  HTTP_TOKEN_WRAP      *Wrap
555   );
556 
557 /**
558   Generate HTTP request string.
559 
560   @param[in]  HttpInstance       Pointer to HTTP_PROTOCOL structure.
561   @param[in]  Message            Pointer to storage containing HTTP message data.
562   @param[in]  Url                The URL of a remote host.
563 
564   @return     Pointer to the created HTTP request string.
565   @return     NULL if any error occured.
566 
567 **/
568 CHAR8 *
569 HttpGenRequestString (
570   IN  HTTP_PROTOCOL        *HttpInstance,
571   IN  EFI_HTTP_MESSAGE     *Message,
572   IN  CHAR8                *Url
573   );
574 
575 /**
576   The work function of EfiHttpResponse().
577 
578   @param[in]  Wrap                Pointer to HTTP token's wrap data.
579 
580   @retval EFI_SUCCESS             Allocation succeeded.
581   @retval EFI_OUT_OF_RESOURCES    Failed to complete the opration due to lack of resources.
582   @retval EFI_NOT_READY           Can't find a corresponding TxToken.
583 
584 **/
585 EFI_STATUS
586 HttpResponseWorker (
587   IN  HTTP_TOKEN_WRAP           *Wrap
588   );
589 
590 #endif
591