NetworkPkg: Convert source file to DOS format
[mirror_edk2.git] / NetworkPkg / HttpDxe / HttpProto.c
CommitLineData
47f51a06
YT
1/** @file\r
2 Miscellaneous routines for HttpDxe driver.\r
3\r
89f06051 4Copyright (c) 2015 - 2017, Intel Corporation. All rights reserved.<BR>\r
90f658c4 5(C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>\r
47f51a06
YT
6This program and the accompanying materials\r
7are licensed and made available under the terms and conditions of the BSD License\r
8which accompanies this distribution. The full text of the license may be found at\r
9http://opensource.org/licenses/bsd-license.php\r
10\r
11THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
12WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
13\r
14**/\r
15\r
16#include "HttpDriver.h"\r
17\r
18/**\r
19 The common notify function used in HTTP driver. \r
20\r
21 @param[in] Event The event signaled.\r
22 @param[in] Context The context.\r
23\r
24**/\r
25VOID\r
26EFIAPI\r
27HttpCommonNotify (\r
28 IN EFI_EVENT Event,\r
29 IN VOID *Context\r
30 )\r
31{\r
32 if ((Event == NULL) || (Context == NULL)) {\r
33 return ;\r
34 }\r
35\r
36 *((BOOLEAN *) Context) = TRUE;\r
37}\r
38\r
39/**\r
b659408b 40 The notify function associated with Tx4Token for Tcp4->Transmit() or Tx6Token for Tcp6->Transmit().\r
47f51a06 41\r
47f51a06
YT
42 @param[in] Context The context.\r
43\r
44**/\r
45VOID\r
46EFIAPI\r
49c9f74c 47HttpTcpTransmitNotifyDpc (\r
47f51a06
YT
48 IN VOID *Context\r
49 )\r
50{\r
51 HTTP_TOKEN_WRAP *Wrap;\r
b659408b 52 HTTP_PROTOCOL *HttpInstance;\r
47f51a06 53\r
49c9f74c 54 if (Context == NULL) {\r
47f51a06
YT
55 return ;\r
56 }\r
b659408b
ZL
57 \r
58 Wrap = (HTTP_TOKEN_WRAP *) Context;\r
59 HttpInstance = Wrap->HttpInstance;\r
60 \r
61 if (!HttpInstance->LocalAddressIsIPv6) {\r
62 Wrap->HttpToken->Status = Wrap->TcpWrap.Tx4Token.CompletionToken.Status;\r
63 gBS->SignalEvent (Wrap->HttpToken->Event);\r
64\r
65 //\r
66 // Free resources.\r
67 //\r
68 if (Wrap->TcpWrap.Tx4Token.Packet.TxData->FragmentTable[0].FragmentBuffer != NULL) {\r
69 FreePool (Wrap->TcpWrap.Tx4Token.Packet.TxData->FragmentTable[0].FragmentBuffer);\r
70 }\r
47f51a06 71\r
b659408b
ZL
72 if (Wrap->TcpWrap.Tx4Token.CompletionToken.Event != NULL) {\r
73 gBS->CloseEvent (Wrap->TcpWrap.Tx4Token.CompletionToken.Event);\r
74 }\r
75 \r
76 } else {\r
77 Wrap->HttpToken->Status = Wrap->TcpWrap.Tx6Token.CompletionToken.Status;\r
78 gBS->SignalEvent (Wrap->HttpToken->Event);\r
79 \r
80 //\r
81 // Free resources.\r
82 //\r
83 if (Wrap->TcpWrap.Tx6Token.Packet.TxData->FragmentTable[0].FragmentBuffer != NULL) {\r
84 FreePool (Wrap->TcpWrap.Tx6Token.Packet.TxData->FragmentTable[0].FragmentBuffer);\r
85 }\r
47f51a06 86\r
b659408b
ZL
87 if (Wrap->TcpWrap.Tx6Token.CompletionToken.Event != NULL) {\r
88 gBS->CloseEvent (Wrap->TcpWrap.Tx6Token.CompletionToken.Event);\r
89 } \r
47f51a06
YT
90 }\r
91\r
47f51a06
YT
92\r
93 Wrap->TcpWrap.IsTxDone = TRUE;\r
94\r
95 //\r
96 // Check pending TxTokens and sent out.\r
97 //\r
98 NetMapIterate (&Wrap->HttpInstance->TxTokens, HttpTcpTransmit, NULL);\r
99\r
100}\r
101\r
49c9f74c
FS
102/**\r
103 Request HttpTcpTransmitNotifyDpc as a DPC at TPL_CALLBACK.\r
104\r
105 @param Event The receive event delivered to TCP for transmit.\r
106 @param Context Context for the callback.\r
107\r
108**/\r
109VOID\r
110EFIAPI\r
111HttpTcpTransmitNotify (\r
112 IN EFI_EVENT Event,\r
113 IN VOID *Context\r
114 )\r
115{\r
116 //\r
117 // Request HttpTcpTransmitNotifyDpc as a DPC at TPL_CALLBACK\r
118 //\r
119 QueueDpc (TPL_CALLBACK, HttpTcpTransmitNotifyDpc, Context);\r
120}\r
121\r
47f51a06 122/**\r
b659408b 123 The notify function associated with Rx4Token for Tcp4->Receive () or Rx6Token for Tcp6->Receive().\r
47f51a06 124\r
47f51a06
YT
125 @param[in] Context The context.\r
126\r
127**/\r
128VOID\r
129EFIAPI\r
49c9f74c 130HttpTcpReceiveNotifyDpc (\r
47f51a06
YT
131 IN VOID *Context\r
132 )\r
133{\r
134 HTTP_TOKEN_WRAP *Wrap;\r
135 NET_MAP_ITEM *Item;\r
136 UINTN Length;\r
137 EFI_STATUS Status;\r
138 HTTP_PROTOCOL *HttpInstance;\r
b659408b 139 BOOLEAN UsingIpv6;\r
47f51a06 140\r
49c9f74c 141 if (Context == NULL) {\r
47f51a06
YT
142 return ;\r
143 }\r
144\r
145 Wrap = (HTTP_TOKEN_WRAP *) Context;\r
47f51a06 146 HttpInstance = Wrap->HttpInstance;\r
b659408b
ZL
147 UsingIpv6 = HttpInstance->LocalAddressIsIPv6;\r
148 \r
149 if (UsingIpv6) {\r
150 gBS->CloseEvent (Wrap->TcpWrap.Rx6Token.CompletionToken.Event);\r
30526a51 151 Wrap->TcpWrap.Rx6Token.CompletionToken.Event = NULL;\r
b659408b
ZL
152 \r
153 if (EFI_ERROR (Wrap->TcpWrap.Rx6Token.CompletionToken.Status)) {\r
30526a51 154 DEBUG ((EFI_D_ERROR, "HttpTcpReceiveNotifyDpc: %r!\n", Wrap->TcpWrap.Rx6Token.CompletionToken.Status));\r
621a618a
ZL
155 Wrap->HttpToken->Status = Wrap->TcpWrap.Rx6Token.CompletionToken.Status;\r
156 gBS->SignalEvent (Wrap->HttpToken->Event);\r
30526a51
JW
157\r
158 Item = NetMapFindKey (&HttpInstance->RxTokens, Wrap->HttpToken);\r
159 if (Item != NULL) {\r
160 NetMapRemoveItem (&HttpInstance->RxTokens, Item, NULL);\r
161 }\r
162 \r
163 FreePool (Wrap);\r
164 Wrap = NULL;\r
165 \r
b659408b
ZL
166 return ;\r
167 }\r
168\r
169 } else {\r
170 gBS->CloseEvent (Wrap->TcpWrap.Rx4Token.CompletionToken.Event);\r
30526a51 171 Wrap->TcpWrap.Rx4Token.CompletionToken.Event = NULL;\r
b659408b
ZL
172 \r
173 if (EFI_ERROR (Wrap->TcpWrap.Rx4Token.CompletionToken.Status)) {\r
30526a51 174 DEBUG ((EFI_D_ERROR, "HttpTcpReceiveNotifyDpc: %r!\n", Wrap->TcpWrap.Rx4Token.CompletionToken.Status));\r
621a618a
ZL
175 Wrap->HttpToken->Status = Wrap->TcpWrap.Rx4Token.CompletionToken.Status;\r
176 gBS->SignalEvent (Wrap->HttpToken->Event);\r
30526a51
JW
177 \r
178 Item = NetMapFindKey (&HttpInstance->RxTokens, Wrap->HttpToken);\r
179 if (Item != NULL) {\r
180 NetMapRemoveItem (&HttpInstance->RxTokens, Item, NULL);\r
181 }\r
182 \r
183 FreePool (Wrap);\r
184 Wrap = NULL;\r
185 \r
b659408b
ZL
186 return ;\r
187 }\r
188 }\r
47f51a06
YT
189\r
190 //\r
191 // Check whether we receive a complete HTTP message.\r
192 //\r
193 ASSERT (HttpInstance->MsgParser != NULL);\r
b659408b
ZL
194 if (UsingIpv6) {\r
195 Length = (UINTN) Wrap->TcpWrap.Rx6Data.FragmentTable[0].FragmentLength;\r
196 } else {\r
197 Length = (UINTN) Wrap->TcpWrap.Rx4Data.FragmentTable[0].FragmentLength;\r
198 }\r
47f51a06 199\r
47f51a06
YT
200 Status = HttpParseMessageBody (\r
201 HttpInstance->MsgParser,\r
202 Length,\r
203 Wrap->HttpToken->Message->Body\r
204 );\r
205 if (EFI_ERROR (Status)) {\r
206 return ;\r
207 }\r
208\r
209 if (HttpIsMessageComplete (HttpInstance->MsgParser)) {\r
210 //\r
211 // Free the MsgParse since we already have a full HTTP message.\r
212 //\r
213 HttpFreeMsgParser (HttpInstance->MsgParser);\r
214 HttpInstance->MsgParser = NULL;\r
215 }\r
216\r
217 Wrap->HttpToken->Message->BodyLength = Length;\r
218 ASSERT (HttpInstance->CacheBody == NULL);\r
219 //\r
220 // We receive part of header of next HTTP msg.\r
221 //\r
222 if (HttpInstance->NextMsg != NULL) {\r
223 Wrap->HttpToken->Message->BodyLength = HttpInstance->NextMsg - \r
224 (CHAR8 *) Wrap->HttpToken->Message->Body;\r
225 HttpInstance->CacheLen = Length - Wrap->HttpToken->Message->BodyLength;\r
226 if (HttpInstance->CacheLen != 0) {\r
227 HttpInstance->CacheBody = AllocateZeroPool (HttpInstance->CacheLen);\r
228 if (HttpInstance->CacheBody == NULL) {\r
229 return ;\r
230 }\r
231 CopyMem (HttpInstance->CacheBody, HttpInstance->NextMsg, HttpInstance->CacheLen);\r
232 HttpInstance->NextMsg = HttpInstance->CacheBody;\r
233 HttpInstance->CacheOffset = 0;\r
234 }\r
235 }\r
236\r
237 Item = NetMapFindKey (&Wrap->HttpInstance->RxTokens, Wrap->HttpToken);\r
238 if (Item != NULL) {\r
239 NetMapRemoveItem (&Wrap->HttpInstance->RxTokens, Item, NULL);\r
240 }\r
241\r
242\r
243 Wrap->TcpWrap.IsRxDone = TRUE;\r
b659408b
ZL
244 if (UsingIpv6) {\r
245 Wrap->HttpToken->Status = Wrap->TcpWrap.Rx6Token.CompletionToken.Status;\r
246 } else {\r
247 Wrap->HttpToken->Status = Wrap->TcpWrap.Rx4Token.CompletionToken.Status;\r
248 }\r
249 \r
47f51a06
YT
250\r
251 gBS->SignalEvent (Wrap->HttpToken->Event);\r
252\r
253 //\r
254 // Check pending RxTokens and receive the HTTP message.\r
255 //\r
256 NetMapIterate (&Wrap->HttpInstance->RxTokens, HttpTcpReceive, NULL);\r
30526a51
JW
257\r
258 FreePool (Wrap);\r
259 Wrap = NULL;\r
47f51a06
YT
260}\r
261\r
49c9f74c
FS
262/**\r
263 Request HttpTcpReceiveNotifyDpc as a DPC at TPL_CALLBACK.\r
264\r
265 @param Event The receive event delivered to TCP for receive.\r
266 @param Context Context for the callback.\r
267\r
268**/\r
269VOID\r
270EFIAPI\r
271HttpTcpReceiveNotify (\r
272 IN EFI_EVENT Event,\r
273 IN VOID *Context\r
274 )\r
275{\r
276 //\r
277 // Request HttpTcpTransmitNotifyDpc as a DPC at TPL_CALLBACK\r
278 //\r
279 QueueDpc (TPL_CALLBACK, HttpTcpReceiveNotifyDpc, Context);\r
280}\r
281\r
47f51a06 282/**\r
b659408b 283 Create events for the TCP connection token and TCP close token.\r
47f51a06
YT
284\r
285 @param[in] HttpInstance Pointer to HTTP_PROTOCOL structure.\r
286\r
287 @retval EFI_SUCCESS The events are created successfully.\r
288 @retval others Other error as indicated.\r
289\r
290**/\r
291EFI_STATUS\r
b659408b 292HttpCreateTcpConnCloseEvent (\r
47f51a06
YT
293 IN HTTP_PROTOCOL *HttpInstance\r
294 )\r
295{\r
296 EFI_STATUS Status;\r
b659408b
ZL
297\r
298 if (!HttpInstance->LocalAddressIsIPv6) {\r
47f51a06
YT
299 //\r
300 // Create events for variuos asynchronous operations.\r
301 //\r
302 Status = gBS->CreateEvent (\r
303 EVT_NOTIFY_SIGNAL,\r
304 TPL_NOTIFY,\r
305 HttpCommonNotify,\r
b659408b
ZL
306 &HttpInstance->IsTcp4ConnDone,\r
307 &HttpInstance->Tcp4ConnToken.CompletionToken.Event\r
47f51a06
YT
308 );\r
309 if (EFI_ERROR (Status)) {\r
310 goto ERROR;\r
311 }\r
312\r
313 //\r
b659408b
ZL
314 // Initialize Tcp4CloseToken\r
315 //\r
316 Status = gBS->CreateEvent (\r
317 EVT_NOTIFY_SIGNAL,\r
318 TPL_NOTIFY,\r
319 HttpCommonNotify,\r
320 &HttpInstance->IsTcp4CloseDone,\r
321 &HttpInstance->Tcp4CloseToken.CompletionToken.Event\r
322 );\r
323 if (EFI_ERROR (Status)) {\r
324 goto ERROR;\r
325 }\r
326 \r
327 } else {\r
328 //\r
329 // Create events for variuos asynchronous operations.\r
47f51a06
YT
330 //\r
331 Status = gBS->CreateEvent (\r
332 EVT_NOTIFY_SIGNAL,\r
333 TPL_NOTIFY,\r
334 HttpCommonNotify,\r
b659408b
ZL
335 &HttpInstance->IsTcp6ConnDone,\r
336 &HttpInstance->Tcp6ConnToken.CompletionToken.Event\r
47f51a06
YT
337 );\r
338 if (EFI_ERROR (Status)) {\r
339 goto ERROR;\r
340 }\r
341\r
b659408b
ZL
342 //\r
343 // Initialize Tcp6CloseToken\r
344 //\r
345 Status = gBS->CreateEvent (\r
346 EVT_NOTIFY_SIGNAL,\r
347 TPL_NOTIFY,\r
348 HttpCommonNotify,\r
349 &HttpInstance->IsTcp6CloseDone,\r
350 &HttpInstance->Tcp6CloseToken.CompletionToken.Event\r
351 );\r
352 if (EFI_ERROR (Status)) {\r
353 goto ERROR;\r
354 }\r
355 }\r
356 \r
47f51a06
YT
357 return EFI_SUCCESS;\r
358\r
359ERROR:\r
360 //\r
361 // Error handling\r
362 //\r
b659408b 363 HttpCloseTcpConnCloseEvent (HttpInstance);\r
47f51a06
YT
364\r
365 return Status;\r
366}\r
367\r
368\r
369/**\r
b659408b 370 Close events in the TCP connection token and TCP close token.\r
47f51a06
YT
371\r
372 @param[in] HttpInstance Pointer to HTTP_PROTOCOL structure.\r
373\r
374**/\r
375VOID\r
b659408b 376HttpCloseTcpConnCloseEvent (\r
47f51a06
YT
377 IN HTTP_PROTOCOL *HttpInstance\r
378 )\r
379{\r
380 ASSERT (HttpInstance != NULL);\r
381\r
b659408b
ZL
382 if (HttpInstance->LocalAddressIsIPv6) {\r
383 if (NULL != HttpInstance->Tcp6ConnToken.CompletionToken.Event) {\r
384 gBS->CloseEvent (HttpInstance->Tcp6ConnToken.CompletionToken.Event);\r
385 HttpInstance->Tcp6ConnToken.CompletionToken.Event = NULL;\r
386 }\r
47f51a06 387\r
b659408b
ZL
388 if (NULL != HttpInstance->Tcp6CloseToken.CompletionToken.Event) {\r
389 gBS->CloseEvent(HttpInstance->Tcp6CloseToken.CompletionToken.Event);\r
390 HttpInstance->Tcp6CloseToken.CompletionToken.Event = NULL;\r
391 }\r
392\r
393 } else {\r
394 if (NULL != HttpInstance->Tcp4ConnToken.CompletionToken.Event) {\r
395 gBS->CloseEvent (HttpInstance->Tcp4ConnToken.CompletionToken.Event);\r
396 HttpInstance->Tcp4ConnToken.CompletionToken.Event = NULL;\r
397 }\r
398\r
399 if (NULL != HttpInstance->Tcp4CloseToken.CompletionToken.Event) {\r
400 gBS->CloseEvent(HttpInstance->Tcp4CloseToken.CompletionToken.Event);\r
401 HttpInstance->Tcp4CloseToken.CompletionToken.Event = NULL;\r
402 }\r
403 }\r
404 \r
47f51a06
YT
405}\r
406\r
407/**\r
b659408b 408 Create event for the TCP transmit token.\r
47f51a06
YT
409\r
410 @param[in] Wrap Point to HTTP token's wrap data.\r
411\r
412 @retval EFI_SUCCESS The events is created successfully.\r
413 @retval others Other error as indicated.\r
414\r
415**/\r
416EFI_STATUS\r
b659408b 417HttpCreateTcpTxEvent (\r
47f51a06
YT
418 IN HTTP_TOKEN_WRAP *Wrap\r
419 )\r
420{\r
421 EFI_STATUS Status;\r
b659408b 422 HTTP_PROTOCOL *HttpInstance;\r
47f51a06
YT
423 HTTP_TCP_TOKEN_WRAP *TcpWrap;\r
424\r
b659408b 425 HttpInstance = Wrap->HttpInstance;\r
47f51a06
YT
426 TcpWrap = &Wrap->TcpWrap;\r
427\r
b659408b
ZL
428 if (!HttpInstance->LocalAddressIsIPv6) {\r
429 Status = gBS->CreateEvent (\r
430 EVT_NOTIFY_SIGNAL,\r
431 TPL_NOTIFY,\r
432 HttpTcpTransmitNotify,\r
433 Wrap,\r
434 &TcpWrap->Tx4Token.CompletionToken.Event\r
435 );\r
30526a51
JW
436 if (EFI_ERROR (Status)) {\r
437 return Status;\r
438 }\r
439 \r
440 TcpWrap->Tx4Data.Push = TRUE;\r
441 TcpWrap->Tx4Data.Urgent = FALSE;\r
442 TcpWrap->Tx4Data.FragmentCount = 1;\r
443 TcpWrap->Tx4Token.Packet.TxData = &Wrap->TcpWrap.Tx4Data;\r
444 TcpWrap->Tx4Token.CompletionToken.Status = EFI_NOT_READY;\r
47f51a06 445\r
b659408b
ZL
446 } else {\r
447 Status = gBS->CreateEvent (\r
448 EVT_NOTIFY_SIGNAL,\r
449 TPL_NOTIFY,\r
450 HttpTcpTransmitNotify,\r
451 Wrap,\r
452 &TcpWrap->Tx6Token.CompletionToken.Event\r
453 );\r
454 if (EFI_ERROR (Status)) {\r
455 return Status;\r
456 }\r
47f51a06 457\r
b659408b
ZL
458 TcpWrap->Tx6Data.Push = TRUE;\r
459 TcpWrap->Tx6Data.Urgent = FALSE;\r
460 TcpWrap->Tx6Data.FragmentCount = 1;\r
461 TcpWrap->Tx6Token.Packet.TxData = &Wrap->TcpWrap.Tx6Data;\r
462 TcpWrap->Tx6Token.CompletionToken.Status =EFI_NOT_READY;\r
463 \r
b659408b
ZL
464 }\r
465 \r
47f51a06
YT
466 return EFI_SUCCESS;\r
467}\r
468\r
469/**\r
b659408b 470 Create event for the TCP receive token which is used to receive HTTP header.\r
47f51a06
YT
471\r
472 @param[in] HttpInstance Pointer to HTTP_PROTOCOL structure.\r
473\r
474 @retval EFI_SUCCESS The events is created successfully.\r
475 @retval others Other error as indicated.\r
476\r
477**/\r
478EFI_STATUS\r
b659408b 479HttpCreateTcpRxEventForHeader (\r
47f51a06
YT
480 IN HTTP_PROTOCOL *HttpInstance\r
481 )\r
482{\r
483 EFI_STATUS Status;\r
484\r
b659408b
ZL
485 if (!HttpInstance->LocalAddressIsIPv6) {\r
486 Status = gBS->CreateEvent (\r
487 EVT_NOTIFY_SIGNAL,\r
488 TPL_NOTIFY,\r
489 HttpCommonNotify,\r
490 &HttpInstance->IsRxDone,\r
491 &HttpInstance->Rx4Token.CompletionToken.Event\r
492 );\r
493 if (EFI_ERROR (Status)) {\r
494 return Status;\r
495 }\r
496 \r
497 HttpInstance->Rx4Data.FragmentCount = 1;\r
498 HttpInstance->Rx4Token.Packet.RxData = &HttpInstance->Rx4Data;\r
499 HttpInstance->Rx4Token.CompletionToken.Status = EFI_NOT_READY;\r
47f51a06 500\r
b659408b
ZL
501 } else {\r
502 Status = gBS->CreateEvent (\r
503 EVT_NOTIFY_SIGNAL,\r
504 TPL_NOTIFY,\r
505 HttpCommonNotify,\r
506 &HttpInstance->IsRxDone,\r
507 &HttpInstance->Rx6Token.CompletionToken.Event\r
508 );\r
509 if (EFI_ERROR (Status)) {\r
510 return Status;\r
511 }\r
512\r
513 HttpInstance->Rx6Data.FragmentCount =1;\r
514 HttpInstance->Rx6Token.Packet.RxData = &HttpInstance->Rx6Data;\r
515 HttpInstance->Rx6Token.CompletionToken.Status = EFI_NOT_READY;\r
516 \r
47f51a06
YT
517 }\r
518\r
47f51a06
YT
519\r
520 return EFI_SUCCESS;\r
521}\r
522\r
523/**\r
b659408b 524 Create event for the TCP receive token which is used to receive HTTP body.\r
47f51a06
YT
525\r
526 @param[in] Wrap Point to HTTP token's wrap data.\r
527\r
528 @retval EFI_SUCCESS The events is created successfully.\r
529 @retval others Other error as indicated.\r
530\r
531**/\r
532EFI_STATUS\r
b659408b 533HttpCreateTcpRxEvent (\r
47f51a06
YT
534 IN HTTP_TOKEN_WRAP *Wrap \r
535 )\r
536{\r
537 EFI_STATUS Status;\r
b659408b 538 HTTP_PROTOCOL *HttpInstance;\r
47f51a06
YT
539 HTTP_TCP_TOKEN_WRAP *TcpWrap;\r
540\r
b659408b 541 HttpInstance = Wrap->HttpInstance;\r
47f51a06 542 TcpWrap = &Wrap->TcpWrap;\r
b659408b
ZL
543 if (!HttpInstance->LocalAddressIsIPv6) {\r
544 Status = gBS->CreateEvent (\r
545 EVT_NOTIFY_SIGNAL,\r
546 TPL_NOTIFY,\r
547 HttpTcpReceiveNotify,\r
548 Wrap,\r
549 &TcpWrap->Rx4Token.CompletionToken.Event\r
550 );\r
551 if (EFI_ERROR (Status)) {\r
552 return Status;\r
553 }\r
554 \r
555 TcpWrap->Rx4Data.FragmentCount = 1;\r
556 TcpWrap->Rx4Token.Packet.RxData = &Wrap->TcpWrap.Rx4Data;\r
557 TcpWrap->Rx4Token.CompletionToken.Status = EFI_NOT_READY;\r
47f51a06 558\r
b659408b
ZL
559 } else {\r
560 Status = gBS->CreateEvent (\r
561 EVT_NOTIFY_SIGNAL,\r
562 TPL_NOTIFY,\r
563 HttpTcpReceiveNotify,\r
564 Wrap,\r
565 &TcpWrap->Rx6Token.CompletionToken.Event\r
566 ); \r
567 if (EFI_ERROR (Status)) {\r
568 return Status;\r
569 }\r
570\r
571 TcpWrap->Rx6Data.FragmentCount = 1;\r
572 TcpWrap->Rx6Token.Packet.RxData = &Wrap->TcpWrap.Rx6Data;\r
573 TcpWrap->Rx6Token.CompletionToken.Status = EFI_NOT_READY;\r
47f51a06 574 }\r
b659408b
ZL
575 \r
576 return EFI_SUCCESS;\r
577}\r
47f51a06 578\r
b659408b
ZL
579/**\r
580 Close Events for Tcp Receive Tokens for HTTP body and HTTP header.\r
47f51a06 581\r
b659408b
ZL
582 @param[in] Wrap Pointer to HTTP token's wrap data.\r
583 \r
584**/\r
585VOID\r
586HttpCloseTcpRxEvent (\r
587 IN HTTP_TOKEN_WRAP *Wrap\r
588 )\r
589{\r
590 HTTP_PROTOCOL *HttpInstance;\r
b659408b 591\r
1b96428d 592 ASSERT (Wrap != NULL);\r
b659408b 593 HttpInstance = Wrap->HttpInstance;\r
b659408b
ZL
594 \r
595 if (HttpInstance->LocalAddressIsIPv6) {\r
1b96428d
ZL
596 if (Wrap->TcpWrap.Rx6Token.CompletionToken.Event != NULL) {\r
597 gBS->CloseEvent (Wrap->TcpWrap.Rx6Token.CompletionToken.Event);\r
b659408b
ZL
598 }\r
599\r
600 if (HttpInstance->Rx6Token.CompletionToken.Event != NULL) {\r
601 gBS->CloseEvent (HttpInstance->Rx6Token.CompletionToken.Event);\r
602 HttpInstance->Rx6Token.CompletionToken.Event = NULL;\r
603 }\r
604 } else {\r
1b96428d
ZL
605 if (Wrap->TcpWrap.Rx4Token.CompletionToken.Event != NULL) {\r
606 gBS->CloseEvent (Wrap->TcpWrap.Rx4Token.CompletionToken.Event);\r
b659408b
ZL
607 }\r
608 \r
609 if (HttpInstance->Rx4Token.CompletionToken.Event != NULL) {\r
610 gBS->CloseEvent (HttpInstance->Rx4Token.CompletionToken.Event);\r
611 HttpInstance->Rx4Token.CompletionToken.Event = NULL;\r
612 }\r
613 }\r
47f51a06
YT
614}\r
615\r
616/**\r
617 Intiialize the HTTP_PROTOCOL structure to the unconfigured state.\r
618\r
47f51a06 619 @param[in, out] HttpInstance Pointer to HTTP_PROTOCOL structure.\r
b659408b 620 @param[in] IpVersion Indicate us TCP4 protocol or TCP6 protocol.\r
47f51a06
YT
621\r
622 @retval EFI_SUCCESS HTTP_PROTOCOL structure is initialized successfully. \r
623 @retval Others Other error as indicated.\r
624\r
625**/\r
626EFI_STATUS\r
627HttpInitProtocol (\r
b659408b
ZL
628 IN OUT HTTP_PROTOCOL *HttpInstance,\r
629 IN BOOLEAN IpVersion\r
47f51a06
YT
630 )\r
631{\r
632 EFI_STATUS Status;\r
633 VOID *Interface;\r
b659408b
ZL
634 BOOLEAN UsingIpv6;\r
635 \r
636 ASSERT (HttpInstance != NULL);\r
637 UsingIpv6 = IpVersion;\r
638 \r
639 if (!UsingIpv6) {\r
640 //\r
641 // Create TCP4 child.\r
642 //\r
643 Status = NetLibCreateServiceChild (\r
644 HttpInstance->Service->ControllerHandle,\r
7cf59c85 645 HttpInstance->Service->Ip4DriverBindingHandle,\r
b659408b
ZL
646 &gEfiTcp4ServiceBindingProtocolGuid,\r
647 &HttpInstance->Tcp4ChildHandle\r
648 );\r
47f51a06 649\r
b659408b
ZL
650 if (EFI_ERROR (Status)) {\r
651 goto ON_ERROR;\r
652 }\r
47f51a06 653\r
b659408b
ZL
654 Status = gBS->OpenProtocol (\r
655 HttpInstance->Tcp4ChildHandle,\r
656 &gEfiTcp4ProtocolGuid,\r
657 (VOID **) &Interface,\r
7cf59c85 658 HttpInstance->Service->Ip4DriverBindingHandle,\r
b659408b
ZL
659 HttpInstance->Service->ControllerHandle,\r
660 EFI_OPEN_PROTOCOL_BY_DRIVER\r
661 );\r
662 \r
663 if (EFI_ERROR (Status)) {\r
664 goto ON_ERROR;\r
665 }\r
47f51a06 666\r
b659408b
ZL
667 Status = gBS->OpenProtocol (\r
668 HttpInstance->Tcp4ChildHandle,\r
669 &gEfiTcp4ProtocolGuid,\r
670 (VOID **) &HttpInstance->Tcp4,\r
7cf59c85 671 HttpInstance->Service->Ip4DriverBindingHandle,\r
b659408b
ZL
672 HttpInstance->Handle,\r
673 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
674 );\r
675 if (EFI_ERROR(Status)) {\r
676 goto ON_ERROR;\r
677 }\r
47f51a06 678\r
b659408b
ZL
679 Status = gBS->OpenProtocol (\r
680 HttpInstance->Service->Tcp4ChildHandle,\r
681 &gEfiTcp4ProtocolGuid,\r
682 (VOID **) &Interface,\r
7cf59c85 683 HttpInstance->Service->Ip4DriverBindingHandle,\r
b659408b
ZL
684 HttpInstance->Handle,\r
685 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
686 );\r
687 if (EFI_ERROR(Status)) {\r
688 goto ON_ERROR;\r
689 }\r
690 } else {\r
691 //\r
692 // Create TCP6 Child.\r
693 //\r
694 Status = NetLibCreateServiceChild (\r
695 HttpInstance->Service->ControllerHandle,\r
7cf59c85 696 HttpInstance->Service->Ip6DriverBindingHandle,\r
b659408b
ZL
697 &gEfiTcp6ServiceBindingProtocolGuid,\r
698 &HttpInstance->Tcp6ChildHandle\r
699 );\r
47f51a06 700\r
b659408b
ZL
701 if (EFI_ERROR (Status)) {\r
702 goto ON_ERROR;\r
703 }\r
47f51a06 704\r
b659408b
ZL
705 Status = gBS->OpenProtocol (\r
706 HttpInstance->Tcp6ChildHandle,\r
707 &gEfiTcp6ProtocolGuid,\r
708 (VOID **) &Interface,\r
7cf59c85 709 HttpInstance->Service->Ip6DriverBindingHandle,\r
b659408b
ZL
710 HttpInstance->Service->ControllerHandle,\r
711 EFI_OPEN_PROTOCOL_BY_DRIVER\r
712 );\r
713 \r
714 if (EFI_ERROR (Status)) {\r
715 goto ON_ERROR;\r
716 }\r
717\r
718 Status = gBS->OpenProtocol (\r
719 HttpInstance->Tcp6ChildHandle,\r
720 &gEfiTcp6ProtocolGuid,\r
721 (VOID **) &HttpInstance->Tcp6,\r
7cf59c85 722 HttpInstance->Service->Ip6DriverBindingHandle,\r
b659408b
ZL
723 HttpInstance->Handle,\r
724 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
725 );\r
726 \r
727 if (EFI_ERROR(Status)) {\r
728 goto ON_ERROR;\r
729 } \r
730\r
731 Status = gBS->OpenProtocol (\r
732 HttpInstance->Service->Tcp6ChildHandle,\r
733 &gEfiTcp6ProtocolGuid,\r
734 (VOID **) &Interface,\r
7cf59c85 735 HttpInstance->Service->Ip6DriverBindingHandle,\r
b659408b
ZL
736 HttpInstance->Handle,\r
737 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
738 );\r
47f51a06 739\r
b659408b
ZL
740 if (EFI_ERROR(Status)) {\r
741 goto ON_ERROR;\r
742 }\r
743 }\r
744 \r
51b0450e
FS
745 HttpInstance->Url = AllocateZeroPool (HTTP_URL_BUFFER_LEN);\r
746 if (HttpInstance->Url == NULL) {\r
747 Status = EFI_OUT_OF_RESOURCES;\r
748 goto ON_ERROR;\r
749 }\r
750\r
47f51a06
YT
751 return EFI_SUCCESS;\r
752\r
753ON_ERROR:\r
754 \r
b659408b 755 if (HttpInstance->Tcp4ChildHandle != NULL) {\r
47f51a06 756 gBS->CloseProtocol (\r
b659408b 757 HttpInstance->Tcp4ChildHandle,\r
47f51a06 758 &gEfiTcp4ProtocolGuid,\r
7cf59c85 759 HttpInstance->Service->Ip4DriverBindingHandle,\r
47f51a06
YT
760 HttpInstance->Service->ControllerHandle\r
761 );\r
762\r
763 gBS->CloseProtocol (\r
b659408b 764 HttpInstance->Tcp4ChildHandle,\r
47f51a06 765 &gEfiTcp4ProtocolGuid,\r
7cf59c85 766 HttpInstance->Service->Ip4DriverBindingHandle,\r
47f51a06 767 HttpInstance->Handle\r
b659408b 768 ); \r
47f51a06
YT
769 \r
770 NetLibDestroyServiceChild (\r
771 HttpInstance->Service->ControllerHandle,\r
7cf59c85 772 HttpInstance->Service->Ip4DriverBindingHandle,\r
47f51a06 773 &gEfiTcp4ServiceBindingProtocolGuid,\r
b659408b 774 HttpInstance->Tcp4ChildHandle\r
47f51a06
YT
775 );\r
776 }\r
b659408b
ZL
777 \r
778 if (HttpInstance->Service->Tcp4ChildHandle != NULL) {\r
779 gBS->CloseProtocol (\r
780 HttpInstance->Service->Tcp4ChildHandle,\r
781 &gEfiTcp4ProtocolGuid,\r
7cf59c85 782 HttpInstance->Service->Ip4DriverBindingHandle,\r
b659408b
ZL
783 HttpInstance->Handle\r
784 );\r
785 }\r
786 \r
787 if (HttpInstance->Tcp6ChildHandle != NULL) {\r
788 gBS->CloseProtocol (\r
789 HttpInstance->Tcp6ChildHandle,\r
790 &gEfiTcp6ProtocolGuid,\r
7cf59c85 791 HttpInstance->Service->Ip6DriverBindingHandle,\r
b659408b
ZL
792 HttpInstance->Service->ControllerHandle\r
793 );\r
47f51a06 794\r
b659408b
ZL
795 gBS->CloseProtocol (\r
796 HttpInstance->Tcp6ChildHandle,\r
797 &gEfiTcp6ProtocolGuid,\r
7cf59c85 798 HttpInstance->Service->Ip6DriverBindingHandle,\r
b659408b
ZL
799 HttpInstance->Handle\r
800 );\r
801 \r
802 NetLibDestroyServiceChild (\r
803 HttpInstance->Service->ControllerHandle,\r
7cf59c85 804 HttpInstance->Service->Ip6DriverBindingHandle,\r
b659408b
ZL
805 &gEfiTcp6ServiceBindingProtocolGuid,\r
806 HttpInstance->Tcp6ChildHandle\r
807 );\r
808 }\r
809 \r
810 if (HttpInstance->Service->Tcp6ChildHandle != NULL) {\r
811 gBS->CloseProtocol (\r
812 HttpInstance->Service->Tcp6ChildHandle,\r
813 &gEfiTcp6ProtocolGuid,\r
7cf59c85 814 HttpInstance->Service->Ip6DriverBindingHandle,\r
b659408b
ZL
815 HttpInstance->Handle\r
816 );\r
817 }\r
818\r
819 return EFI_UNSUPPORTED;\r
47f51a06
YT
820 \r
821}\r
822\r
823/**\r
824 Clean up the HTTP child, release all the resources used by it.\r
825\r
826 @param[in] HttpInstance The HTTP child to clean up.\r
827\r
828**/\r
829VOID\r
830HttpCleanProtocol (\r
831 IN HTTP_PROTOCOL *HttpInstance\r
832 )\r
833{\r
834 HttpCloseConnection (HttpInstance);\r
835 \r
b659408b 836 HttpCloseTcpConnCloseEvent (HttpInstance);\r
47f51a06 837\r
b347a22a
JW
838 if (HttpInstance->TimeoutEvent != NULL) {\r
839 gBS->CloseEvent (HttpInstance->TimeoutEvent);\r
840 HttpInstance->TimeoutEvent = NULL;\r
841 }\r
842\r
47f51a06
YT
843 if (HttpInstance->CacheBody != NULL) {\r
844 FreePool (HttpInstance->CacheBody);\r
845 HttpInstance->CacheBody = NULL;\r
846 HttpInstance->NextMsg = NULL;\r
847 }\r
848\r
849 if (HttpInstance->RemoteHost != NULL) {\r
850 FreePool (HttpInstance->RemoteHost);\r
851 HttpInstance->RemoteHost = NULL;\r
852 }\r
853\r
854 if (HttpInstance->MsgParser != NULL) {\r
855 HttpFreeMsgParser (HttpInstance->MsgParser);\r
856 HttpInstance->MsgParser = NULL;\r
857 }\r
b659408b 858 \r
51b0450e
FS
859 if (HttpInstance->Url != NULL) {\r
860 FreePool (HttpInstance->Url);\r
861 HttpInstance->Url = NULL;\r
862 }\r
b659408b 863 \r
47f51a06
YT
864 NetMapClean (&HttpInstance->TxTokens);\r
865 NetMapClean (&HttpInstance->RxTokens);\r
866\r
45ea8a0c
JW
867 if (HttpInstance->TlsSb != NULL && HttpInstance->TlsChildHandle != NULL) {\r
868 //\r
869 // Destroy the TLS instance. \r
328141fc 870 //\r
45ea8a0c
JW
871 HttpInstance->TlsSb->DestroyChild (HttpInstance->TlsSb, HttpInstance->TlsChildHandle);\r
872 }\r
873\r
b659408b 874 if (HttpInstance->Tcp4ChildHandle != NULL) {\r
47f51a06 875 gBS->CloseProtocol (\r
b659408b 876 HttpInstance->Tcp4ChildHandle,\r
47f51a06 877 &gEfiTcp4ProtocolGuid,\r
7cf59c85 878 HttpInstance->Service->Ip4DriverBindingHandle,\r
47f51a06
YT
879 HttpInstance->Service->ControllerHandle\r
880 );\r
881\r
882 gBS->CloseProtocol (\r
b659408b 883 HttpInstance->Tcp4ChildHandle,\r
47f51a06 884 &gEfiTcp4ProtocolGuid,\r
7cf59c85 885 HttpInstance->Service->Ip4DriverBindingHandle,\r
47f51a06
YT
886 HttpInstance->Handle\r
887 );\r
888 \r
889 NetLibDestroyServiceChild (\r
890 HttpInstance->Service->ControllerHandle,\r
7cf59c85 891 HttpInstance->Service->Ip4DriverBindingHandle,\r
47f51a06 892 &gEfiTcp4ServiceBindingProtocolGuid,\r
b659408b 893 HttpInstance->Tcp4ChildHandle\r
47f51a06
YT
894 );\r
895 }\r
b659408b
ZL
896\r
897 if (HttpInstance->Service->Tcp4ChildHandle != NULL) {\r
898 gBS->CloseProtocol (\r
899 HttpInstance->Service->Tcp4ChildHandle,\r
900 &gEfiTcp4ProtocolGuid,\r
7cf59c85 901 HttpInstance->Service->Ip4DriverBindingHandle,\r
b659408b
ZL
902 HttpInstance->Handle\r
903 );\r
904 } \r
905\r
906 if (HttpInstance->Tcp6ChildHandle != NULL) {\r
907 gBS->CloseProtocol (\r
908 HttpInstance->Tcp6ChildHandle,\r
909 &gEfiTcp6ProtocolGuid,\r
7cf59c85 910 HttpInstance->Service->Ip6DriverBindingHandle,\r
b659408b
ZL
911 HttpInstance->Service->ControllerHandle\r
912 );\r
913\r
914 gBS->CloseProtocol (\r
915 HttpInstance->Tcp6ChildHandle,\r
916 &gEfiTcp6ProtocolGuid,\r
7cf59c85 917 HttpInstance->Service->Ip6DriverBindingHandle,\r
b659408b
ZL
918 HttpInstance->Handle\r
919 );\r
920 \r
921 NetLibDestroyServiceChild (\r
922 HttpInstance->Service->ControllerHandle,\r
7cf59c85 923 HttpInstance->Service->Ip6DriverBindingHandle,\r
b659408b
ZL
924 &gEfiTcp6ServiceBindingProtocolGuid,\r
925 HttpInstance->Tcp6ChildHandle\r
926 );\r
927 }\r
928 \r
929 if (HttpInstance->Service->Tcp6ChildHandle != NULL) {\r
930 gBS->CloseProtocol (\r
931 HttpInstance->Service->Tcp6ChildHandle,\r
932 &gEfiTcp6ProtocolGuid,\r
7cf59c85 933 HttpInstance->Service->Ip6DriverBindingHandle,\r
b659408b
ZL
934 HttpInstance->Handle\r
935 );\r
936 }\r
dac45de3
JW
937\r
938 TlsCloseTxRxEvent (HttpInstance); \r
47f51a06
YT
939}\r
940\r
941/**\r
942 Establish TCP connection with HTTP server.\r
943\r
944 @param[in] HttpInstance The HTTP instance private data.\r
945\r
946 @retval EFI_SUCCESS The TCP connection is established.\r
947 @retval Others Other error as indicated.\r
948\r
949**/\r
950EFI_STATUS\r
951HttpCreateConnection (\r
952 IN HTTP_PROTOCOL *HttpInstance\r
953 )\r
954{\r
955 EFI_STATUS Status;\r
956\r
47f51a06
YT
957 //\r
958 // Connect to Http server\r
959 //\r
b659408b
ZL
960 if (!HttpInstance->LocalAddressIsIPv6) {\r
961 HttpInstance->IsTcp4ConnDone = FALSE;\r
962 HttpInstance->Tcp4ConnToken.CompletionToken.Status = EFI_NOT_READY;\r
963 Status = HttpInstance->Tcp4->Connect (HttpInstance->Tcp4, &HttpInstance->Tcp4ConnToken);\r
964 if (EFI_ERROR (Status)) {\r
965 DEBUG ((EFI_D_ERROR, "HttpCreateConnection: Tcp4->Connect() = %r\n", Status));\r
966 return Status;\r
967 }\r
968 \r
969 while (!HttpInstance->IsTcp4ConnDone) {\r
970 HttpInstance->Tcp4->Poll (HttpInstance->Tcp4);\r
971 }\r
972 \r
973 Status = HttpInstance->Tcp4ConnToken.CompletionToken.Status;\r
974 \r
975 } else {\r
976 HttpInstance->IsTcp6ConnDone = FALSE;\r
977 HttpInstance->Tcp6ConnToken.CompletionToken.Status = EFI_NOT_READY;\r
978 Status = HttpInstance->Tcp6->Connect (HttpInstance->Tcp6, &HttpInstance->Tcp6ConnToken);\r
979 if (EFI_ERROR (Status)) {\r
980 DEBUG ((EFI_D_ERROR, "HttpCreateConnection: Tcp6->Connect() = %r\n", Status));\r
981 return Status;\r
982 }\r
47f51a06 983\r
b659408b
ZL
984 while(!HttpInstance->IsTcp6ConnDone) {\r
985 HttpInstance->Tcp6->Poll (HttpInstance->Tcp6);\r
986 }\r
47f51a06 987\r
b659408b
ZL
988 Status = HttpInstance->Tcp6ConnToken.CompletionToken.Status; \r
989 }\r
990 \r
47f51a06
YT
991 if (!EFI_ERROR (Status)) {\r
992 HttpInstance->State = HTTP_STATE_TCP_CONNECTED;\r
993 }\r
994\r
995 return Status;\r
996}\r
997\r
998/**\r
999 Close existing TCP connection.\r
1000\r
1001 @param[in] HttpInstance The HTTP instance private data.\r
1002\r
1003 @retval EFI_SUCCESS The TCP connection is closed.\r
1004 @retval Others Other error as indicated.\r
1005\r
1006**/\r
1007EFI_STATUS\r
1008HttpCloseConnection (\r
1009 IN HTTP_PROTOCOL *HttpInstance\r
1010 )\r
1011{\r
1012 EFI_STATUS Status;\r
1013\r
374ecd04 1014 if (HttpInstance->State == HTTP_STATE_TCP_CONNECTED) {\r
47f51a06 1015\r
b659408b
ZL
1016 if (HttpInstance->LocalAddressIsIPv6) {\r
1017 HttpInstance->Tcp6CloseToken.AbortOnClose = TRUE;\r
1018 HttpInstance->IsTcp6CloseDone = FALSE;\r
1019 Status = HttpInstance->Tcp6->Close (HttpInstance->Tcp6, &HttpInstance->Tcp6CloseToken);\r
1020 if (EFI_ERROR (Status)) {\r
1021 return Status;\r
1022 }\r
1023\r
1024 while (!HttpInstance->IsTcp6CloseDone) {\r
1025 HttpInstance->Tcp6->Poll (HttpInstance->Tcp6);\r
1026 }\r
1027 \r
1028 } else {\r
1029 HttpInstance->Tcp4CloseToken.AbortOnClose = TRUE;\r
1030 HttpInstance->IsTcp4CloseDone = FALSE;\r
1031 Status = HttpInstance->Tcp4->Close (HttpInstance->Tcp4, &HttpInstance->Tcp4CloseToken);\r
1032 if (EFI_ERROR (Status)) {\r
1033 return Status;\r
1034 }\r
1035\r
1036 while (!HttpInstance->IsTcp4CloseDone) {\r
1037 HttpInstance->Tcp4->Poll (HttpInstance->Tcp4);\r
1038 }\r
374ecd04 1039 }\r
b659408b 1040\r
47f51a06
YT
1041 }\r
1042\r
1043 HttpInstance->State = HTTP_STATE_TCP_CLOSED;\r
374ecd04 1044 return EFI_SUCCESS;\r
47f51a06
YT
1045}\r
1046\r
1047/**\r
1048 Configure TCP4 protocol child.\r
1049\r
1050 @param[in] HttpInstance The HTTP instance private data.\r
1051 @param[in] Wrap The HTTP token's wrap data.\r
1052\r
1053 @retval EFI_SUCCESS The TCP4 protocol child is configured.\r
1054 @retval Others Other error as indicated.\r
1055\r
1056**/\r
1057EFI_STATUS\r
1058HttpConfigureTcp4 (\r
1059 IN HTTP_PROTOCOL *HttpInstance,\r
1060 IN HTTP_TOKEN_WRAP *Wrap\r
1061 )\r
1062{\r
1063 EFI_STATUS Status;\r
1064 EFI_TCP4_CONFIG_DATA *Tcp4CfgData;\r
1065 EFI_TCP4_ACCESS_POINT *Tcp4AP;\r
1066 EFI_TCP4_OPTION *Tcp4Option;\r
47f51a06
YT
1067\r
1068 ASSERT (HttpInstance != NULL);\r
47f51a06
YT
1069\r
1070\r
1071 Tcp4CfgData = &HttpInstance->Tcp4CfgData;\r
1072 ZeroMem (Tcp4CfgData, sizeof (EFI_TCP4_CONFIG_DATA));\r
1073 \r
1074 Tcp4CfgData->TypeOfService = HTTP_TOS_DEAULT;\r
1075 Tcp4CfgData->TimeToLive = HTTP_TTL_DEAULT;\r
1076 Tcp4CfgData->ControlOption = &HttpInstance->Tcp4Option;\r
1077\r
1078 Tcp4AP = &Tcp4CfgData->AccessPoint;\r
1079 Tcp4AP->UseDefaultAddress = HttpInstance->IPv4Node.UseDefaultAddress;\r
1080 if (!Tcp4AP->UseDefaultAddress) {\r
1081 IP4_COPY_ADDRESS (&Tcp4AP->StationAddress, &HttpInstance->IPv4Node.LocalAddress);\r
1082 IP4_COPY_ADDRESS (&Tcp4AP->SubnetMask, &HttpInstance->IPv4Node.LocalSubnet);\r
1083 }\r
1084 \r
1085 Tcp4AP->StationPort = HttpInstance->IPv4Node.LocalPort;\r
1086 Tcp4AP->RemotePort = HttpInstance->RemotePort;\r
1087 Tcp4AP->ActiveFlag = TRUE;\r
1088 IP4_COPY_ADDRESS (&Tcp4AP->RemoteAddress, &HttpInstance->RemoteAddr);\r
1089\r
1090 Tcp4Option = Tcp4CfgData->ControlOption;\r
1091 Tcp4Option->ReceiveBufferSize = HTTP_BUFFER_SIZE_DEAULT;\r
1092 Tcp4Option->SendBufferSize = HTTP_BUFFER_SIZE_DEAULT;\r
1093 Tcp4Option->MaxSynBackLog = HTTP_MAX_SYN_BACK_LOG;\r
1094 Tcp4Option->ConnectionTimeout = HTTP_CONNECTION_TIMEOUT;\r
1095 Tcp4Option->DataRetries = HTTP_DATA_RETRIES;\r
1096 Tcp4Option->FinTimeout = HTTP_FIN_TIMEOUT;\r
1097 Tcp4Option->KeepAliveProbes = HTTP_KEEP_ALIVE_PROBES;\r
1098 Tcp4Option->KeepAliveTime = HTTP_KEEP_ALIVE_TIME;\r
1099 Tcp4Option->KeepAliveInterval = HTTP_KEEP_ALIVE_INTERVAL;\r
1100 Tcp4Option->EnableNagle = TRUE;\r
1101 Tcp4CfgData->ControlOption = Tcp4Option;\r
1102\r
1103 Status = HttpInstance->Tcp4->Configure (HttpInstance->Tcp4, Tcp4CfgData);\r
1104 if (EFI_ERROR (Status)) {\r
1105 DEBUG ((EFI_D_ERROR, "HttpConfigureTcp4 - %r\n", Status));\r
1106 return Status;\r
1107 }\r
1108\r
b659408b
ZL
1109 Status = HttpCreateTcpConnCloseEvent (HttpInstance);\r
1110 if (EFI_ERROR (Status)) {\r
1111 return Status;\r
1112 }\r
1113\r
1114 Status = HttpCreateTcpTxEvent (Wrap);\r
1115 if (EFI_ERROR (Status)) {\r
1116 return Status;\r
1117 }\r
1118\r
1119 HttpInstance->State = HTTP_STATE_TCP_CONFIGED;\r
1120\r
1121 return EFI_SUCCESS;\r
1122}\r
1123\r
1124/**\r
1125 Configure TCP6 protocol child.\r
1126\r
1127 @param[in] HttpInstance The HTTP instance private data.\r
1128 @param[in] Wrap The HTTP token's wrap data.\r
1129\r
1130 @retval EFI_SUCCESS The TCP6 protocol child is configured.\r
1131 @retval Others Other error as indicated.\r
1132\r
1133**/\r
1134EFI_STATUS\r
1135HttpConfigureTcp6 (\r
1136 IN HTTP_PROTOCOL *HttpInstance,\r
1137 IN HTTP_TOKEN_WRAP *Wrap\r
1138 )\r
1139{\r
1140 EFI_STATUS Status;\r
1141 EFI_TCP6_CONFIG_DATA *Tcp6CfgData;\r
1142 EFI_TCP6_ACCESS_POINT *Tcp6Ap;\r
1143 EFI_TCP6_OPTION *Tcp6Option;\r
1144 \r
1145 ASSERT (HttpInstance != NULL);\r
1146 \r
1147 Tcp6CfgData = &HttpInstance->Tcp6CfgData;\r
1148 ZeroMem (Tcp6CfgData, sizeof (EFI_TCP6_CONFIG_DATA));\r
1149\r
1150 Tcp6CfgData->TrafficClass = 0;\r
1151 Tcp6CfgData->HopLimit = 255;\r
1152 Tcp6CfgData->ControlOption = &HttpInstance->Tcp6Option;\r
1153 \r
1154 Tcp6Ap = &Tcp6CfgData->AccessPoint;\r
1155 Tcp6Ap->ActiveFlag = TRUE;\r
1156 Tcp6Ap->StationPort = HttpInstance->Ipv6Node.LocalPort;\r
1157 Tcp6Ap->RemotePort = HttpInstance->RemotePort;\r
1158 IP6_COPY_ADDRESS (&Tcp6Ap->StationAddress, &HttpInstance->Ipv6Node.LocalAddress);\r
1159 IP6_COPY_ADDRESS (&Tcp6Ap->RemoteAddress , &HttpInstance->RemoteIpv6Addr);\r
1160\r
1161 Tcp6Option = Tcp6CfgData->ControlOption;\r
1162 Tcp6Option->ReceiveBufferSize = HTTP_BUFFER_SIZE_DEAULT;\r
1163 Tcp6Option->SendBufferSize = HTTP_BUFFER_SIZE_DEAULT;\r
1164 Tcp6Option->MaxSynBackLog = HTTP_MAX_SYN_BACK_LOG;\r
1165 Tcp6Option->ConnectionTimeout = HTTP_CONNECTION_TIMEOUT;\r
1166 Tcp6Option->DataRetries = HTTP_DATA_RETRIES;\r
1167 Tcp6Option->FinTimeout = HTTP_FIN_TIMEOUT;\r
1168 Tcp6Option->KeepAliveProbes = HTTP_KEEP_ALIVE_PROBES;\r
1169 Tcp6Option->KeepAliveTime = HTTP_KEEP_ALIVE_TIME;\r
1170 Tcp6Option->KeepAliveInterval = HTTP_KEEP_ALIVE_INTERVAL;\r
1171 Tcp6Option->EnableNagle = TRUE;\r
1172\r
1173 Status = HttpInstance->Tcp6->Configure (HttpInstance->Tcp6, Tcp6CfgData);\r
1174 if (EFI_ERROR (Status)) {\r
1175 DEBUG ((EFI_D_ERROR, "HttpConfigureTcp6 - %r\n", Status));\r
1176 return Status;\r
1177 }\r
1178 \r
1179 Status = HttpCreateTcpConnCloseEvent (HttpInstance);\r
47f51a06
YT
1180 if (EFI_ERROR (Status)) {\r
1181 return Status;\r
1182 }\r
1183\r
b659408b 1184 Status = HttpCreateTcpTxEvent (Wrap);\r
47f51a06
YT
1185 if (EFI_ERROR (Status)) {\r
1186 return Status;\r
1187 }\r
1188\r
1189 HttpInstance->State = HTTP_STATE_TCP_CONFIGED;\r
1190\r
1191 return EFI_SUCCESS;\r
b659408b 1192 \r
47f51a06
YT
1193}\r
1194\r
1195/**\r
dac45de3
JW
1196 Check existing TCP connection, if in error state, recover TCP4 connection. Then, \r
1197 connect one TLS session if required.\r
47f51a06
YT
1198\r
1199 @param[in] HttpInstance The HTTP instance private data.\r
1200\r
1201 @retval EFI_SUCCESS The TCP connection is established.\r
1202 @retval EFI_NOT_READY TCP4 protocol child is not created or configured.\r
1203 @retval Others Other error as indicated.\r
1204\r
1205**/\r
1206EFI_STATUS\r
1207HttpConnectTcp4 (\r
1208 IN HTTP_PROTOCOL *HttpInstance\r
1209 )\r
1210{\r
1211 EFI_STATUS Status;\r
1212 EFI_TCP4_CONNECTION_STATE Tcp4State;\r
1213\r
1214\r
a2e61982 1215 if (HttpInstance->State < HTTP_STATE_TCP_CONFIGED || HttpInstance->Tcp4 == NULL) {\r
47f51a06
YT
1216 return EFI_NOT_READY;\r
1217 }\r
1218\r
1219 Status = HttpInstance->Tcp4->GetModeData(\r
1220 HttpInstance->Tcp4, \r
1221 &Tcp4State, \r
1222 NULL,\r
1223 NULL,\r
1224 NULL,\r
1225 NULL\r
1226 );\r
1227 if (EFI_ERROR(Status)){\r
1228 DEBUG ((EFI_D_ERROR, "Tcp4 GetModeData fail - %x\n", Status));\r
1229 return Status;\r
1230 }\r
1231\r
a2e61982
ZL
1232 if (Tcp4State == Tcp4StateEstablished) {\r
1233 return EFI_SUCCESS;\r
1234 } else if (Tcp4State > Tcp4StateEstablished ) {\r
47f51a06 1235 HttpCloseConnection(HttpInstance);\r
a2e61982 1236 }\r
47f51a06 1237\r
dac45de3
JW
1238 Status = HttpCreateConnection (HttpInstance);\r
1239 if (EFI_ERROR(Status)){\r
1240 DEBUG ((EFI_D_ERROR, "Tcp4 Connection fail - %x\n", Status));\r
1241 return Status;\r
1242 }\r
1243 \r
1244 //\r
1245 // Tls session connection.\r
1246 //\r
1247 if (HttpInstance->UseHttps) {\r
1248 if (HttpInstance->TimeoutEvent == NULL) {\r
1249 //\r
1250 // Create TimeoutEvent for TLS connection.\r
1251 //\r
1252 Status = gBS->CreateEvent (\r
1253 EVT_TIMER,\r
1254 TPL_CALLBACK,\r
1255 NULL,\r
1256 NULL,\r
1257 &HttpInstance->TimeoutEvent\r
1258 );\r
1259 if (EFI_ERROR (Status)) {\r
1260 TlsCloseTxRxEvent (HttpInstance);\r
1261 return Status;\r
1262 }\r
1263 }\r
1264\r
1265 //\r
1266 // Start the timer, and wait Timeout seconds for connection.\r
1267 //\r
1268 Status = gBS->SetTimer (HttpInstance->TimeoutEvent, TimerRelative, HTTP_CONNECTION_TIMEOUT * TICKS_PER_SECOND);\r
1269 if (EFI_ERROR (Status)) {\r
1270 TlsCloseTxRxEvent (HttpInstance);\r
1271 return Status;\r
1272 }\r
1273 \r
1274 Status = TlsConnectSession (HttpInstance, HttpInstance->TimeoutEvent);\r
1275\r
1276 gBS->SetTimer (HttpInstance->TimeoutEvent, TimerCancel, 0);\r
1277 \r
1278 if (EFI_ERROR (Status)) {\r
1279 TlsCloseTxRxEvent (HttpInstance);\r
1280 return Status;\r
1281 }\r
1282 }\r
1283\r
1284 return Status;\r
47f51a06
YT
1285}\r
1286\r
1287/**\r
dac45de3
JW
1288 Check existing TCP connection, if in error state, recover TCP6 connection. Then, \r
1289 connect one TLS session if required.\r
b659408b
ZL
1290\r
1291 @param[in] HttpInstance The HTTP instance private data.\r
1292\r
1293 @retval EFI_SUCCESS The TCP connection is established.\r
1294 @retval EFI_NOT_READY TCP6 protocol child is not created or configured.\r
1295 @retval Others Other error as indicated.\r
1296\r
1297**/\r
1298EFI_STATUS\r
1299HttpConnectTcp6 (\r
1300 IN HTTP_PROTOCOL *HttpInstance\r
1301 )\r
1302{\r
1303 EFI_STATUS Status;\r
1304 EFI_TCP6_CONNECTION_STATE Tcp6State;\r
1305\r
a2e61982 1306 if (HttpInstance->State < HTTP_STATE_TCP_CONFIGED || HttpInstance->Tcp6 == NULL) {\r
b659408b
ZL
1307 return EFI_NOT_READY;\r
1308 }\r
1309\r
1310 Status = HttpInstance->Tcp6->GetModeData (\r
1311 HttpInstance->Tcp6,\r
1312 &Tcp6State,\r
1313 NULL,\r
1314 NULL,\r
1315 NULL,\r
1316 NULL\r
1317 );\r
1318 \r
1319 if (EFI_ERROR(Status)){\r
1320 DEBUG ((EFI_D_ERROR, "Tcp6 GetModeData fail - %x\n", Status));\r
1321 return Status;\r
1322 }\r
1323\r
a2e61982
ZL
1324 if (Tcp6State == Tcp6StateEstablished) {\r
1325 return EFI_SUCCESS;\r
1326 } else if (Tcp6State > Tcp6StateEstablished ) {\r
1327 HttpCloseConnection(HttpInstance);\r
b659408b
ZL
1328 }\r
1329\r
dac45de3
JW
1330 Status = HttpCreateConnection (HttpInstance);\r
1331 if (EFI_ERROR(Status)){\r
1332 DEBUG ((EFI_D_ERROR, "Tcp6 Connection fail - %x\n", Status));\r
1333 return Status;\r
1334 }\r
1335 \r
1336 //\r
1337 // Tls session connection.\r
1338 //\r
1339 if (HttpInstance->UseHttps) {\r
1340 if (HttpInstance->TimeoutEvent == NULL) {\r
1341 //\r
1342 // Create TimeoutEvent for TLS connection.\r
1343 //\r
1344 Status = gBS->CreateEvent (\r
1345 EVT_TIMER,\r
1346 TPL_CALLBACK,\r
1347 NULL,\r
1348 NULL,\r
1349 &HttpInstance->TimeoutEvent\r
1350 );\r
1351 if (EFI_ERROR (Status)) {\r
1352 TlsCloseTxRxEvent (HttpInstance);\r
1353 return Status;\r
1354 }\r
1355 }\r
1356\r
1357 //\r
1358 // Start the timer, and wait Timeout seconds for connection.\r
1359 //\r
1360 Status = gBS->SetTimer (HttpInstance->TimeoutEvent, TimerRelative, HTTP_CONNECTION_TIMEOUT * TICKS_PER_SECOND);\r
1361 if (EFI_ERROR (Status)) {\r
1362 TlsCloseTxRxEvent (HttpInstance);\r
1363 return Status;\r
1364 }\r
1365 \r
1366 Status = TlsConnectSession (HttpInstance, HttpInstance->TimeoutEvent);\r
1367\r
1368 gBS->SetTimer (HttpInstance->TimeoutEvent, TimerCancel, 0);\r
1369 \r
1370 if (EFI_ERROR (Status)) {\r
1371 TlsCloseTxRxEvent (HttpInstance);\r
1372 return Status;\r
1373 }\r
1374 }\r
1375\r
1376 return Status;\r
b659408b
ZL
1377}\r
1378\r
1379/**\r
dac45de3 1380 Initialize Http session.\r
b659408b
ZL
1381\r
1382 @param[in] HttpInstance The HTTP instance private data.\r
1383 @param[in] Wrap The HTTP token's wrap data.\r
dac45de3
JW
1384 @param[in] Configure The Flag indicates whether need to initialize session.\r
1385 @param[in] TlsConfigure The Flag indicates whether it's the new Tls session.\r
b659408b 1386\r
dac45de3 1387 @retval EFI_SUCCESS The initialization of session is done. \r
b659408b
ZL
1388 @retval Others Other error as indicated.\r
1389\r
1390**/\r
1391EFI_STATUS\r
dac45de3 1392HttpInitSession (\r
b659408b 1393 IN HTTP_PROTOCOL *HttpInstance,\r
a2e61982 1394 IN HTTP_TOKEN_WRAP *Wrap,\r
dac45de3
JW
1395 IN BOOLEAN Configure,\r
1396 IN BOOLEAN TlsConfigure\r
b659408b
ZL
1397 )\r
1398{\r
1399 EFI_STATUS Status;\r
1400 ASSERT (HttpInstance != NULL);\r
1401\r
dac45de3
JW
1402 //\r
1403 // Configure Tls session.\r
1404 //\r
1405 if (TlsConfigure) {\r
1406 Status = TlsConfigureSession (HttpInstance);\r
1407 if (EFI_ERROR (Status)) {\r
1408 return Status;\r
1409 }\r
1410 }\r
1411\r
b659408b
ZL
1412 if (!HttpInstance->LocalAddressIsIPv6) {\r
1413 //\r
1414 // Configure TCP instance.\r
1415 //\r
a2e61982
ZL
1416 if (Configure) {\r
1417 Status = HttpConfigureTcp4 (HttpInstance, Wrap);\r
1418 if (EFI_ERROR (Status)) {\r
1419 return Status;\r
1420 }\r
b659408b 1421 }\r
a2e61982 1422\r
b659408b
ZL
1423 //\r
1424 // Connect TCP.\r
1425 //\r
1426 Status = HttpConnectTcp4 (HttpInstance);\r
1427 if (EFI_ERROR (Status)) {\r
1428 return Status;\r
1429 }\r
1430 } else {\r
1431 //\r
1432 // Configure TCP instance.\r
1433 //\r
a2e61982
ZL
1434 if (Configure) {\r
1435 Status = HttpConfigureTcp6 (HttpInstance, Wrap);\r
1436 if (EFI_ERROR (Status)) {\r
1437 return Status;\r
1438 }\r
b659408b 1439 }\r
a2e61982 1440\r
b659408b
ZL
1441 //\r
1442 // Connect TCP.\r
1443 //\r
1444 Status = HttpConnectTcp6 (HttpInstance);\r
1445 if (EFI_ERROR (Status)) {\r
1446 return Status;\r
1447 }\r
1448 }\r
1449 \r
1450 return EFI_SUCCESS;\r
1451 \r
1452}\r
1453\r
1454/**\r
dac45de3 1455 Send the HTTP or HTTPS message through TCP4 or TCP6.\r
47f51a06
YT
1456\r
1457 @param[in] HttpInstance The HTTP instance private data.\r
1458 @param[in] Wrap The HTTP token's wrap data.\r
1459 @param[in] TxString Buffer containing the HTTP message string.\r
1460 @param[in] TxStringLen Length of the HTTP message string in bytes.\r
1461\r
1462 @retval EFI_SUCCESS The HTTP message is queued into TCP transmit queue.\r
1463 @retval Others Other error as indicated.\r
1464\r
1465**/\r
1466EFI_STATUS\r
b659408b 1467HttpTransmitTcp (\r
47f51a06
YT
1468 IN HTTP_PROTOCOL *HttpInstance,\r
1469 IN HTTP_TOKEN_WRAP *Wrap,\r
1470 IN UINT8 *TxString,\r
1471 IN UINTN TxStringLen\r
1472 )\r
1473{\r
1474 EFI_STATUS Status;\r
b659408b 1475 EFI_TCP4_IO_TOKEN *Tx4Token;\r
47f51a06 1476 EFI_TCP4_PROTOCOL *Tcp4;\r
b659408b
ZL
1477 EFI_TCP6_IO_TOKEN *Tx6Token;\r
1478 EFI_TCP6_PROTOCOL *Tcp6;\r
dac45de3
JW
1479 UINT8 *Buffer; \r
1480 UINTN BufferSize;\r
1481 NET_FRAGMENT TempFragment;\r
1482\r
1483 Status = EFI_SUCCESS;\r
1484 Buffer = NULL;\r
12b96a93
JW
1485 TempFragment.Len = 0;\r
1486 TempFragment.Bulk = NULL;\r
dac45de3
JW
1487\r
1488 //\r
1489 // Need to encrypt data.\r
1490 //\r
1491 if (HttpInstance->UseHttps) {\r
1492 //\r
1493 // Build BufferOut data\r
1494 //\r
1495 BufferSize = sizeof (TLS_RECORD_HEADER) + TxStringLen;\r
1496 Buffer = AllocateZeroPool (BufferSize);\r
1497 if (Buffer == NULL) {\r
1498 Status = EFI_OUT_OF_RESOURCES;\r
1499 return Status;\r
1500 }\r
89f06051 1501 ((TLS_RECORD_HEADER *) Buffer)->ContentType = TlsContentTypeApplicationData;\r
dac45de3
JW
1502 ((TLS_RECORD_HEADER *) Buffer)->Version.Major = HttpInstance->TlsConfigData.Version.Major;\r
1503 ((TLS_RECORD_HEADER *) Buffer)->Version.Minor = HttpInstance->TlsConfigData.Version.Minor;\r
1504 ((TLS_RECORD_HEADER *) Buffer)->Length = (UINT16) (TxStringLen);\r
1505 CopyMem (Buffer + sizeof (TLS_RECORD_HEADER), TxString, TxStringLen);\r
1506 \r
1507 //\r
1508 // Encrypt Packet.\r
1509 //\r
1510 Status = TlsProcessMessage (\r
1511 HttpInstance, \r
1512 Buffer, \r
1513 BufferSize, \r
1514 EfiTlsEncrypt, \r
1515 &TempFragment\r
1516 );\r
1517 \r
1518 FreePool (Buffer);\r
1519\r
1520 if (EFI_ERROR (Status)) {\r
1521 return Status;\r
1522 }\r
1523 }\r
47f51a06 1524 \r
dac45de3 1525 if (!HttpInstance->LocalAddressIsIPv6) {\r
b659408b
ZL
1526 Tcp4 = HttpInstance->Tcp4;\r
1527 Tx4Token = &Wrap->TcpWrap.Tx4Token;\r
dac45de3
JW
1528\r
1529 if (HttpInstance->UseHttps) {\r
1530 Tx4Token->Packet.TxData->DataLength = TempFragment.Len;\r
1531 Tx4Token->Packet.TxData->FragmentTable[0].FragmentLength = TempFragment.Len;\r
1532 Tx4Token->Packet.TxData->FragmentTable[0].FragmentBuffer = (VOID *) TempFragment.Bulk;\r
1533 } else {\r
1534 Tx4Token->Packet.TxData->DataLength = (UINT32) TxStringLen;\r
1535 Tx4Token->Packet.TxData->FragmentTable[0].FragmentLength = (UINT32) TxStringLen;\r
1536 Tx4Token->Packet.TxData->FragmentTable[0].FragmentBuffer = (VOID *) TxString;\r
1537 }\r
b659408b 1538 \r
b659408b
ZL
1539 Tx4Token->CompletionToken.Status = EFI_NOT_READY; \r
1540 \r
1541 Wrap->TcpWrap.IsTxDone = FALSE;\r
1542 Status = Tcp4->Transmit (Tcp4, Tx4Token);\r
1543 if (EFI_ERROR (Status)) {\r
1544 DEBUG ((EFI_D_ERROR, "Transmit failed: %r\n", Status));\r
1545 return Status;\r
1546 }\r
47f51a06 1547\r
b659408b
ZL
1548 } else {\r
1549 Tcp6 = HttpInstance->Tcp6;\r
1550 Tx6Token = &Wrap->TcpWrap.Tx6Token;\r
dac45de3
JW
1551 \r
1552 if (HttpInstance->UseHttps) {\r
1553 Tx6Token->Packet.TxData->DataLength = TempFragment.Len;\r
1554 Tx6Token->Packet.TxData->FragmentTable[0].FragmentLength = TempFragment.Len;\r
1555 Tx6Token->Packet.TxData->FragmentTable[0].FragmentBuffer = (VOID *) TempFragment.Bulk;\r
1556 } else {\r
1557 Tx6Token->Packet.TxData->DataLength = (UINT32) TxStringLen;\r
1558 Tx6Token->Packet.TxData->FragmentTable[0].FragmentLength = (UINT32) TxStringLen;\r
1559 Tx6Token->Packet.TxData->FragmentTable[0].FragmentBuffer = (VOID *) TxString;\r
1560 }\r
1561 \r
b659408b
ZL
1562 Tx6Token->CompletionToken.Status = EFI_NOT_READY;\r
1563\r
1564 Wrap->TcpWrap.IsTxDone = FALSE;\r
1565 Status = Tcp6->Transmit (Tcp6, Tx6Token);\r
1566 if (EFI_ERROR (Status)) {\r
1567 DEBUG ((EFI_D_ERROR, "Transmit failed: %r\n", Status));\r
1568 return Status;\r
1569 }\r
47f51a06 1570 }\r
b659408b 1571 \r
47f51a06
YT
1572 return Status;\r
1573}\r
1574\r
47f51a06
YT
1575/**\r
1576 Check whether the user's token or event has already\r
b659408b 1577 been enqueue on HTTP Tx or Rx Token list.\r
47f51a06
YT
1578\r
1579 @param[in] Map The container of either user's transmit or receive\r
1580 token.\r
1581 @param[in] Item Current item to check against.\r
1582 @param[in] Context The Token to check againist.\r
1583\r
1584 @retval EFI_ACCESS_DENIED The token or event has already been enqueued in IP\r
1585 @retval EFI_SUCCESS The current item isn't the same token/event as the\r
1586 context.\r
1587\r
1588**/\r
1589EFI_STATUS\r
1590EFIAPI\r
1591HttpTokenExist (\r
1592 IN NET_MAP *Map,\r
1593 IN NET_MAP_ITEM *Item,\r
1594 IN VOID *Context\r
1595 )\r
1596{\r
1597 EFI_HTTP_TOKEN *Token;\r
1598 EFI_HTTP_TOKEN *TokenInItem;\r
1599\r
1600 Token = (EFI_HTTP_TOKEN *) Context;\r
1601 TokenInItem = (EFI_HTTP_TOKEN *) Item->Key;\r
1602\r
1603 if (Token == TokenInItem || Token->Event == TokenInItem->Event) {\r
1604 return EFI_ACCESS_DENIED;\r
1605 }\r
1606\r
1607 return EFI_SUCCESS;\r
1608}\r
1609\r
1610/**\r
b659408b 1611 Check whether the HTTP message associated with Tx4Token or Tx6Token is already sent out.\r
47f51a06 1612\r
b659408b 1613 @param[in] Map The container of Tx4Token or Tx6Token.\r
47f51a06
YT
1614 @param[in] Item Current item to check against.\r
1615 @param[in] Context The Token to check againist.\r
1616\r
1617 @retval EFI_NOT_READY The HTTP message is still queued in the list.\r
1618 @retval EFI_SUCCESS The HTTP message has been sent out.\r
1619\r
1620**/\r
1621EFI_STATUS\r
1622EFIAPI\r
1623HttpTcpNotReady (\r
1624 IN NET_MAP *Map,\r
1625 IN NET_MAP_ITEM *Item,\r
1626 IN VOID *Context\r
1627 )\r
1628{\r
1629 HTTP_TOKEN_WRAP *ValueInItem;\r
1630\r
1631 ValueInItem = (HTTP_TOKEN_WRAP *) Item->Value;\r
1632\r
1633 if (!ValueInItem->TcpWrap.IsTxDone) {\r
1634 return EFI_NOT_READY;\r
1635 }\r
1636 \r
1637 return EFI_SUCCESS;\r
1638}\r
1639\r
1640/**\r
dac45de3 1641 Transmit the HTTP or HTTPS mssage by processing the associated HTTP token.\r
47f51a06 1642\r
b659408b 1643 @param[in] Map The container of Tx4Token or Tx6Token.\r
47f51a06
YT
1644 @param[in] Item Current item to check against.\r
1645 @param[in] Context The Token to check againist.\r
1646\r
1647 @retval EFI_OUT_OF_RESOURCES Failed to allocate resources.\r
1648 @retval EFI_SUCCESS The HTTP message is queued into TCP transmit\r
1649 queue.\r
1650\r
1651**/\r
1652EFI_STATUS\r
1653EFIAPI\r
1654HttpTcpTransmit (\r
1655 IN NET_MAP *Map,\r
1656 IN NET_MAP_ITEM *Item,\r
1657 IN VOID *Context\r
1658 )\r
1659{\r
1660 HTTP_TOKEN_WRAP *ValueInItem;\r
1661 EFI_STATUS Status;\r
19c25725 1662 CHAR8 *RequestMsg;\r
47f51a06 1663 CHAR8 *Url;\r
b9679cd7 1664 UINTN UrlSize;\r
19c25725 1665 UINTN RequestMsgSize;\r
47f51a06 1666\r
63f1d6a4
JW
1667 RequestMsg = NULL;\r
1668\r
47f51a06
YT
1669 ValueInItem = (HTTP_TOKEN_WRAP *) Item->Value;\r
1670 if (ValueInItem->TcpWrap.IsTxDone) {\r
1671 return EFI_SUCCESS;\r
1672 }\r
1673\r
1674 //\r
1675 // Parse the URI of the remote host.\r
1676 //\r
b9679cd7
SZ
1677 UrlSize = StrLen (ValueInItem->HttpToken->Message->Data.Request->Url) + 1;\r
1678 Url = AllocatePool (UrlSize);\r
47f51a06
YT
1679 if (Url == NULL) {\r
1680 return EFI_OUT_OF_RESOURCES;\r
1681 }\r
1682\r
b9679cd7 1683 UnicodeStrToAsciiStrS (ValueInItem->HttpToken->Message->Data.Request->Url, Url, UrlSize);\r
47f51a06
YT
1684\r
1685 //\r
1686 // Create request message.\r
1687 //\r
19c25725 1688 Status = HttpGenRequestMessage (\r
47f51a06 1689 ValueInItem->HttpToken->Message,\r
f58554fc 1690 Url,\r
19c25725
NH
1691 &RequestMsg,\r
1692 &RequestMsgSize\r
47f51a06
YT
1693 );\r
1694 FreePool (Url);\r
f58554fc 1695\r
63f1d6a4 1696 if (EFI_ERROR (Status) || NULL == RequestMsg){\r
f58554fc 1697 return Status;\r
47f51a06
YT
1698 }\r
1699\r
63f1d6a4
JW
1700 ASSERT (RequestMsg != NULL);\r
1701\r
47f51a06
YT
1702 //\r
1703 // Transmit the request message.\r
1704 //\r
b659408b 1705 Status = HttpTransmitTcp (\r
47f51a06
YT
1706 ValueInItem->HttpInstance,\r
1707 ValueInItem,\r
19c25725
NH
1708 (UINT8*) RequestMsg,\r
1709 RequestMsgSize\r
47f51a06 1710 );\r
19c25725 1711 FreePool (RequestMsg);\r
47f51a06
YT
1712 return Status;\r
1713}\r
1714\r
1715/**\r
1716 Receive the HTTP response by processing the associated HTTP token.\r
1717\r
b659408b 1718 @param[in] Map The container of Rx4Token or Rx6Token.\r
47f51a06
YT
1719 @param[in] Item Current item to check against.\r
1720 @param[in] Context The Token to check againist.\r
1721\r
1722 @retval EFI_SUCCESS The HTTP response is queued into TCP receive\r
1723 queue.\r
1724 @retval Others Other error as indicated.\r
1725\r
1726**/\r
1727EFI_STATUS\r
1728EFIAPI\r
1729HttpTcpReceive (\r
1730 IN NET_MAP *Map,\r
1731 IN NET_MAP_ITEM *Item,\r
1732 IN VOID *Context\r
1733 )\r
1734{\r
1735 //\r
1736 // Process the queued HTTP response.\r
1737 //\r
1738 return HttpResponseWorker ((HTTP_TOKEN_WRAP *) Item->Value);\r
1739}\r
1740\r
b659408b
ZL
1741/**\r
1742 Receive the HTTP header by processing the associated HTTP token.\r
1743\r
1744 @param[in] HttpInstance The HTTP instance private data.\r
1745 @param[in, out] SizeofHeaders The HTTP header length.\r
1746 @param[in, out] BufferSize The size of buffer to cacahe the header message.\r
b347a22a 1747 @param[in] Timeout The time to wait for receiving the header packet.\r
b659408b
ZL
1748 \r
1749 @retval EFI_SUCCESS The HTTP header is received. \r
1750 @retval Others Other errors as indicated.\r
1751\r
1752**/\r
1753EFI_STATUS\r
1754HttpTcpReceiveHeader (\r
1755 IN HTTP_PROTOCOL *HttpInstance,\r
1756 IN OUT UINTN *SizeofHeaders,\r
b347a22a
JW
1757 IN OUT UINTN *BufferSize,\r
1758 IN EFI_EVENT Timeout\r
b659408b
ZL
1759 )\r
1760{\r
1761 EFI_STATUS Status;\r
1762 EFI_TCP4_IO_TOKEN *Rx4Token;\r
1763 EFI_TCP4_PROTOCOL *Tcp4;\r
1764 EFI_TCP6_IO_TOKEN *Rx6Token;\r
1765 EFI_TCP6_PROTOCOL *Tcp6;\r
1766 CHAR8 **EndofHeader;\r
1767 CHAR8 **HttpHeaders;\r
1768 CHAR8 *Buffer;\r
dac45de3 1769 NET_FRAGMENT Fragment;\r
b659408b
ZL
1770\r
1771 ASSERT (HttpInstance != NULL);\r
1772\r
1773 EndofHeader = HttpInstance->EndofHeader;\r
1774 HttpHeaders = HttpInstance->HttpHeaders;\r
1775 Tcp4 = HttpInstance->Tcp4;\r
1776 Tcp6 = HttpInstance->Tcp6;\r
1777 Buffer = NULL;\r
1778 Rx4Token = NULL;\r
1779 Rx6Token = NULL;\r
dac45de3
JW
1780 Fragment.Len = 0;\r
1781 Fragment.Bulk = NULL;\r
b659408b
ZL
1782 \r
1783 if (HttpInstance->LocalAddressIsIPv6) {\r
1784 ASSERT (Tcp6 != NULL);\r
1785 } else {\r
1786 ASSERT (Tcp4 != NULL);\r
1787 }\r
1788\r
dac45de3
JW
1789 if (!HttpInstance->UseHttps) {\r
1790 Status = HttpCreateTcpRxEventForHeader (HttpInstance);\r
1791 if (EFI_ERROR (Status)) {\r
b659408b
ZL
1792 return Status;\r
1793 }\r
dac45de3
JW
1794 }\r
1795\r
1796 if (!HttpInstance->LocalAddressIsIPv6) {\r
1797 if (!HttpInstance->UseHttps) {\r
1798 Rx4Token = &HttpInstance->Rx4Token;\r
1799 Rx4Token->Packet.RxData->FragmentTable[0].FragmentBuffer = AllocateZeroPool (DEF_BUF_LEN);\r
1800 if (Rx4Token->Packet.RxData->FragmentTable[0].FragmentBuffer == NULL) {\r
1801 Status = EFI_OUT_OF_RESOURCES;\r
1802 return Status;\r
1803 }\r
1804 }\r
b659408b
ZL
1805 \r
1806 //\r
1807 // Receive the HTTP headers only when EFI_HTTP_RESPONSE_DATA is not NULL.\r
1808 //\r
dac45de3
JW
1809 while (*EndofHeader == NULL) {\r
1810 if (!HttpInstance->UseHttps) {\r
1811 HttpInstance->IsRxDone = FALSE;\r
1812 Rx4Token->Packet.RxData->DataLength = DEF_BUF_LEN;\r
1813 Rx4Token->Packet.RxData->FragmentTable[0].FragmentLength = DEF_BUF_LEN;\r
1814 Status = Tcp4->Receive (Tcp4, Rx4Token);\r
1815 if (EFI_ERROR (Status)) {\r
1816 DEBUG ((EFI_D_ERROR, "Tcp4 receive failed: %r\n", Status));\r
1817 return Status;\r
1818 }\r
1819\r
1820 while (!HttpInstance->IsRxDone && ((Timeout == NULL) || EFI_ERROR (gBS->CheckEvent (Timeout)))) {\r
1821 Tcp4->Poll (Tcp4);\r
1822 }\r
1823\r
1824 if (!HttpInstance->IsRxDone) {\r
1825 //\r
1826 // Cancle the Token before close its Event.\r
1827 //\r
1828 Tcp4->Cancel (HttpInstance->Tcp4, &Rx4Token->CompletionToken);\r
1829 gBS->CloseEvent (Rx4Token->CompletionToken.Event);\r
1830 Rx4Token->CompletionToken.Status = EFI_TIMEOUT;\r
1831 }\r
1832\r
1833 Status = Rx4Token->CompletionToken.Status;\r
1834 if (EFI_ERROR (Status)) {\r
1835 return Status;\r
1836 }\r
1837 \r
1838 Fragment.Len = Rx4Token->Packet.RxData->FragmentTable[0].FragmentLength;\r
1839 Fragment.Bulk = (UINT8 *) Rx4Token->Packet.RxData->FragmentTable[0].FragmentBuffer;\r
1840 } else {\r
1841 if (Fragment.Bulk != NULL) {\r
1842 FreePool (Fragment.Bulk);\r
1843 Fragment.Bulk = NULL;\r
1844 }\r
1845 \r
1846 Status = HttpsReceive (HttpInstance, &Fragment, Timeout);\r
1847 if (EFI_ERROR (Status)) {\r
1848 DEBUG ((EFI_D_ERROR, "Tcp4 receive failed: %r\n", Status));\r
1849 return Status;\r
1850 }\r
b347a22a
JW
1851 }\r
1852\r
b659408b
ZL
1853 //\r
1854 // Append the response string.\r
1855 //\r
dac45de3 1856 *BufferSize = *SizeofHeaders + Fragment.Len;\r
b659408b
ZL
1857 Buffer = AllocateZeroPool (*BufferSize);\r
1858 if (Buffer == NULL) {\r
1859 Status = EFI_OUT_OF_RESOURCES;\r
1860 return Status;\r
1861 }\r
dac45de3 1862\r
b659408b 1863 if (*HttpHeaders != NULL) {\r
dac45de3 1864 CopyMem (Buffer, *HttpHeaders, *SizeofHeaders);\r
b659408b
ZL
1865 FreePool (*HttpHeaders);\r
1866 }\r
dac45de3 1867\r
b659408b 1868 CopyMem (\r
dac45de3
JW
1869 Buffer + *SizeofHeaders,\r
1870 Fragment.Bulk,\r
1871 Fragment.Len\r
b659408b 1872 );\r
dac45de3
JW
1873 *HttpHeaders = Buffer;\r
1874 *SizeofHeaders = *BufferSize;\r
1875\r
b659408b
ZL
1876 //\r
1877 // Check whether we received end of HTTP headers.\r
1878 //\r
19bd1335 1879 *EndofHeader = AsciiStrStr (*HttpHeaders, HTTP_END_OF_HDR_STR);\r
dac45de3 1880 };\r
b659408b 1881 \r
dac45de3
JW
1882 //\r
1883 // Free the buffer.\r
1884 //\r
1885 if (Rx4Token != NULL && Rx4Token->Packet.RxData != NULL && Rx4Token->Packet.RxData->FragmentTable[0].FragmentBuffer != NULL) {\r
1886 FreePool (Rx4Token->Packet.RxData->FragmentTable[0].FragmentBuffer);\r
1887 Rx4Token->Packet.RxData->FragmentTable[0].FragmentBuffer = NULL;\r
1888 Fragment.Bulk = NULL;\r
1889 }\r
1890\r
1891 if (Fragment.Bulk != NULL) {\r
1892 FreePool (Fragment.Bulk);\r
1893 Fragment.Bulk = NULL;\r
1894 } \r
b659408b 1895 } else {\r
dac45de3
JW
1896 if (!HttpInstance->UseHttps) {\r
1897 Rx6Token = &HttpInstance->Rx6Token;\r
1898 Rx6Token->Packet.RxData->FragmentTable[0].FragmentBuffer = AllocateZeroPool (DEF_BUF_LEN);\r
1899 if (Rx6Token->Packet.RxData->FragmentTable[0].FragmentBuffer == NULL) {\r
1900 Status = EFI_OUT_OF_RESOURCES;\r
1901 return Status;\r
1902 }\r
b659408b
ZL
1903 }\r
1904 \r
1905 //\r
1906 // Receive the HTTP headers only when EFI_HTTP_RESPONSE_DATA is not NULL.\r
1907 //\r
dac45de3
JW
1908 while (*EndofHeader == NULL) {\r
1909 if (!HttpInstance->UseHttps) {\r
1910 HttpInstance->IsRxDone = FALSE;\r
1911 Rx6Token->Packet.RxData->DataLength = DEF_BUF_LEN;\r
1912 Rx6Token->Packet.RxData->FragmentTable[0].FragmentLength = DEF_BUF_LEN;\r
1913 Status = Tcp6->Receive (Tcp6, Rx6Token);\r
1914 if (EFI_ERROR (Status)) {\r
1915 DEBUG ((EFI_D_ERROR, "Tcp6 receive failed: %r\n", Status));\r
1916 return Status;\r
1917 }\r
1918\r
1919 while (!HttpInstance->IsRxDone && ((Timeout == NULL) || EFI_ERROR (gBS->CheckEvent (Timeout)))) {\r
1920 Tcp6->Poll (Tcp6);\r
1921 }\r
1922\r
1923 if (!HttpInstance->IsRxDone) {\r
1924 //\r
1925 // Cancle the Token before close its Event.\r
1926 //\r
1927 Tcp6->Cancel (HttpInstance->Tcp6, &Rx6Token->CompletionToken);\r
1928 gBS->CloseEvent (Rx6Token->CompletionToken.Event);\r
1929 Rx6Token->CompletionToken.Status = EFI_TIMEOUT;\r
1930 }\r
1931\r
1932 Status = Rx6Token->CompletionToken.Status;\r
1933 if (EFI_ERROR (Status)) {\r
1934 return Status;\r
1935 }\r
1936 \r
1937 Fragment.Len = Rx6Token->Packet.RxData->FragmentTable[0].FragmentLength;\r
1938 Fragment.Bulk = (UINT8 *) Rx6Token->Packet.RxData->FragmentTable[0].FragmentBuffer;\r
1939 } else {\r
1940 if (Fragment.Bulk != NULL) {\r
1941 FreePool (Fragment.Bulk);\r
1942 Fragment.Bulk = NULL;\r
1943 }\r
1944 \r
1945 Status = HttpsReceive (HttpInstance, &Fragment, Timeout);\r
1946 if (EFI_ERROR (Status)) {\r
1947 DEBUG ((EFI_D_ERROR, "Tcp6 receive failed: %r\n", Status));\r
1948 return Status;\r
1949 }\r
b347a22a
JW
1950 }\r
1951\r
b659408b
ZL
1952 //\r
1953 // Append the response string.\r
1954 //\r
dac45de3 1955 *BufferSize = *SizeofHeaders + Fragment.Len;\r
b659408b
ZL
1956 Buffer = AllocateZeroPool (*BufferSize);\r
1957 if (Buffer == NULL) {\r
1958 Status = EFI_OUT_OF_RESOURCES;\r
1959 return Status;\r
1960 }\r
dac45de3 1961\r
b659408b 1962 if (*HttpHeaders != NULL) {\r
dac45de3 1963 CopyMem (Buffer, *HttpHeaders, *SizeofHeaders);\r
b659408b
ZL
1964 FreePool (*HttpHeaders);\r
1965 }\r
dac45de3 1966\r
b659408b 1967 CopyMem (\r
dac45de3
JW
1968 Buffer + *SizeofHeaders,\r
1969 Fragment.Bulk,\r
1970 Fragment.Len\r
b659408b 1971 );\r
dac45de3
JW
1972 *HttpHeaders = Buffer;\r
1973 *SizeofHeaders = *BufferSize;\r
1974\r
b659408b
ZL
1975 //\r
1976 // Check whether we received end of HTTP headers.\r
1977 //\r
dac45de3
JW
1978 *EndofHeader = AsciiStrStr (*HttpHeaders, HTTP_END_OF_HDR_STR); \r
1979 };\r
1980\r
1981 //\r
1982 // Free the buffer.\r
1983 //\r
1984 if (Rx6Token != NULL && Rx6Token->Packet.RxData != NULL && Rx6Token->Packet.RxData->FragmentTable[0].FragmentBuffer != NULL) {\r
1985 FreePool (Rx6Token->Packet.RxData->FragmentTable[0].FragmentBuffer);\r
1986 Rx6Token->Packet.RxData->FragmentTable[0].FragmentBuffer = NULL;\r
1987 Fragment.Bulk = NULL;\r
1988 }\r
1989\r
1990 if (Fragment.Bulk != NULL) {\r
1991 FreePool (Fragment.Bulk);\r
1992 Fragment.Bulk = NULL;\r
b659408b 1993 }\r
b659408b
ZL
1994 } \r
1995\r
1996 //\r
1997 // Skip the CRLF after the HTTP headers.\r
1998 //\r
b16abfcc
JW
1999 *EndofHeader = *EndofHeader + AsciiStrLen (HTTP_END_OF_HDR_STR);\r
2000\r
2001 *SizeofHeaders = *EndofHeader - *HttpHeaders;\r
b659408b
ZL
2002\r
2003 return EFI_SUCCESS;\r
2004}\r
2005\r
2006/**\r
2007 Receive the HTTP body by processing the associated HTTP token.\r
2008\r
2009 @param[in] Wrap The HTTP token's wrap data.\r
2010 @param[in] HttpMsg The HTTP message data.\r
2011\r
2012 @retval EFI_SUCCESS The HTTP body is received. \r
2013 @retval Others Other error as indicated.\r
2014\r
2015**/\r
2016EFI_STATUS\r
2017HttpTcpReceiveBody (\r
2018 IN HTTP_TOKEN_WRAP *Wrap,\r
30526a51 2019 IN EFI_HTTP_MESSAGE *HttpMsg\r
b659408b
ZL
2020 )\r
2021{\r
2022 EFI_STATUS Status;\r
2023 HTTP_PROTOCOL *HttpInstance;\r
2024 EFI_TCP6_PROTOCOL *Tcp6;\r
2025 EFI_TCP6_IO_TOKEN *Rx6Token;\r
2026 EFI_TCP4_PROTOCOL *Tcp4;\r
2027 EFI_TCP4_IO_TOKEN *Rx4Token;\r
2028 \r
2029 HttpInstance = Wrap->HttpInstance;\r
2030 Tcp4 = HttpInstance->Tcp4;\r
2031 Tcp6 = HttpInstance->Tcp6;\r
2032 Rx4Token = NULL;\r
2033 Rx6Token = NULL;\r
b659408b
ZL
2034 \r
2035 if (HttpInstance->LocalAddressIsIPv6) {\r
2036 ASSERT (Tcp6 != NULL);\r
2037 } else {\r
2038 ASSERT (Tcp4 != NULL);\r
2039 }\r
2040 \r
2041 if (HttpInstance->LocalAddressIsIPv6) {\r
2042 Rx6Token = &Wrap->TcpWrap.Rx6Token;\r
6893b16f
JW
2043 Rx6Token ->Packet.RxData->DataLength = (UINT32) MIN (MAX_UINT32, HttpMsg->BodyLength);\r
2044 Rx6Token ->Packet.RxData->FragmentTable[0].FragmentLength = (UINT32) MIN (MAX_UINT32, HttpMsg->BodyLength);\r
b659408b
ZL
2045 Rx6Token ->Packet.RxData->FragmentTable[0].FragmentBuffer = (VOID *) HttpMsg->Body;\r
2046 Rx6Token->CompletionToken.Status = EFI_NOT_READY;\r
2047\r
2048 Status = Tcp6->Receive (Tcp6, Rx6Token);\r
2049 if (EFI_ERROR (Status)) {\r
2050 DEBUG ((EFI_D_ERROR, "Tcp6 receive failed: %r\n", Status));\r
2051 return Status;\r
2052 }\r
b659408b
ZL
2053 } else {\r
2054 Rx4Token = &Wrap->TcpWrap.Rx4Token;\r
6893b16f
JW
2055 Rx4Token->Packet.RxData->DataLength = (UINT32) MIN (MAX_UINT32, HttpMsg->BodyLength);\r
2056 Rx4Token->Packet.RxData->FragmentTable[0].FragmentLength = (UINT32) MIN (MAX_UINT32, HttpMsg->BodyLength);\r
b659408b
ZL
2057 Rx4Token->Packet.RxData->FragmentTable[0].FragmentBuffer = (VOID *) HttpMsg->Body;\r
2058 \r
2059 Rx4Token->CompletionToken.Status = EFI_NOT_READY;\r
2060 Status = Tcp4->Receive (Tcp4, Rx4Token);\r
2061 if (EFI_ERROR (Status)) {\r
2062 DEBUG ((EFI_D_ERROR, "Tcp4 receive failed: %r\n", Status));\r
2063 return Status;\r
2064 }\r
2065 }\r
2066\r
2067 return EFI_SUCCESS;\r
2068\r
2069}\r
2070\r
2071/**\r
2072 Clean up Tcp Tokens while the Tcp transmission error occurs.\r
2073\r
2074 @param[in] Wrap Pointer to HTTP token's wrap data.\r
2075 \r
2076**/\r
2077VOID\r
2078HttpTcpTokenCleanup (\r
2079 IN HTTP_TOKEN_WRAP *Wrap\r
2080 )\r
2081{ \r
2082 HTTP_PROTOCOL *HttpInstance;\r
2083 EFI_TCP4_IO_TOKEN *Rx4Token;\r
2084 EFI_TCP6_IO_TOKEN *Rx6Token;\r
2085\r
1b96428d 2086 ASSERT (Wrap != NULL);\r
b659408b
ZL
2087 HttpInstance = Wrap->HttpInstance;\r
2088 Rx4Token = NULL;\r
2089 Rx6Token = NULL;\r
2090 \r
2091 if (HttpInstance->LocalAddressIsIPv6) {\r
1b96428d 2092 Rx6Token = &Wrap->TcpWrap.Rx6Token;\r
59844e12
JW
2093 \r
2094 if (Rx6Token->CompletionToken.Event != NULL) {\r
2095 gBS->CloseEvent (Rx6Token->CompletionToken.Event);\r
2096 Rx6Token->CompletionToken.Event = NULL;\r
b659408b
ZL
2097 }\r
2098\r
59844e12 2099 FreePool (Wrap);\r
b659408b
ZL
2100\r
2101 Rx6Token = &HttpInstance->Rx6Token;\r
59844e12
JW
2102 \r
2103 if (Rx6Token->CompletionToken.Event != NULL) {\r
2104 gBS->CloseEvent (Rx6Token->CompletionToken.Event);\r
2105 Rx6Token->CompletionToken.Event = NULL;\r
2106 }\r
2107 \r
b659408b
ZL
2108 if (Rx6Token->Packet.RxData->FragmentTable[0].FragmentBuffer != NULL) {\r
2109 FreePool (Rx6Token->Packet.RxData->FragmentTable[0].FragmentBuffer);\r
2110 Rx6Token->Packet.RxData->FragmentTable[0].FragmentBuffer = NULL;\r
2111 }\r
2112 \r
2113 } else {\r
1b96428d 2114 Rx4Token = &Wrap->TcpWrap.Rx4Token;\r
59844e12
JW
2115 \r
2116 if (Rx4Token->CompletionToken.Event != NULL) {\r
2117 gBS->CloseEvent (Rx4Token->CompletionToken.Event);\r
2118 Rx4Token->CompletionToken.Event = NULL;\r
1b96428d 2119 }\r
59844e12 2120 \r
1b96428d
ZL
2121 FreePool (Wrap);\r
2122\r
59844e12
JW
2123 Rx4Token = &HttpInstance->Rx4Token;\r
2124\r
2125 if (Rx4Token->CompletionToken.Event != NULL) {\r
2126 gBS->CloseEvent (Rx4Token->CompletionToken.Event);\r
2127 Rx4Token->CompletionToken.Event = NULL;\r
b659408b
ZL
2128 }\r
2129 \r
59844e12 2130 \r
b659408b
ZL
2131 if (Rx4Token->Packet.RxData->FragmentTable[0].FragmentBuffer != NULL) {\r
2132 FreePool (Rx4Token->Packet.RxData->FragmentTable[0].FragmentBuffer);\r
2133 Rx4Token->Packet.RxData->FragmentTable[0].FragmentBuffer = NULL;\r
2134 }\r
2135 }\r
2136\r
2137}\r