This patch is used to handle timeout case when downloading
the message. The Status in the token should also be checked
to handle any response error case including timeout case.
Cc: Fu Siyuan <siyuan.fu@intel.com>
Cc: Ye Ting <ting.ye@intel.com>
Cc: Zhang Lubo <lubo.zhang@intel.com>
Cc: Hegde Nagaraj P <nagaraj-p.hegde@hpe.com>
Cc: Gary Lin <glin@suse.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Jiaxin Wu <jiaxin.wu@intel.com>
Reviewed-by: Gary Lin <glin@suse.com>
Reviewed-by: Hegde Nagaraj P <nagaraj-p.hegde@hpe.com>
Reviewed-by: Ye Ting <ting.ye@intel.com>
Tested-by: Gary Lin <glin@suse.com>
Tested-by: Hegde Nagaraj P <nagaraj-p.hegde@hpe.com>
FALSE,\r
&ResponseBody\r
);\r
FALSE,\r
&ResponseBody\r
);\r
- if (EFI_ERROR (Status)) {\r
+ if (EFI_ERROR (Status) || EFI_ERROR (ResponseBody.Status)) {\r
+ if (EFI_ERROR (ResponseBody.Status)) {\r
+ Status = ResponseBody.Status;\r
+ }\r
goto ERROR_6;\r
}\r
ReceivedSize += ResponseBody.BodyLength;\r
goto ERROR_6;\r
}\r
ReceivedSize += ResponseBody.BodyLength;\r
FALSE,\r
&ResponseBody\r
);\r
FALSE,\r
&ResponseBody\r
);\r
- if (EFI_ERROR (Status)) {\r
+ if (EFI_ERROR (Status) || EFI_ERROR (ResponseBody.Status)) {\r
+ if (EFI_ERROR (ResponseBody.Status)) {\r
+ Status = ResponseBody.Status;\r
+ }\r
#define __EFI_HTTP_BOOT_HTTP_H__\r
\r
#define HTTP_BOOT_REQUEST_TIMEOUT 5000 // 5 seconds in uints of millisecond.\r
#define __EFI_HTTP_BOOT_HTTP_H__\r
\r
#define HTTP_BOOT_REQUEST_TIMEOUT 5000 // 5 seconds in uints of millisecond.\r
+#define HTTP_BOOT_RESPONSE_TIMEOUT 5000 // 5 seconds in uints of millisecond.\r
#define HTTP_BOOT_BLOCK_SIZE 1500\r
\r
\r
#define HTTP_BOOT_BLOCK_SIZE 1500\r
\r
\r
HttpIo->RspToken.Event = Event;\r
HttpIo->RspToken.Message = &HttpIo->RspMessage;\r
\r
HttpIo->RspToken.Event = Event;\r
HttpIo->RspToken.Message = &HttpIo->RspMessage;\r
\r
+ //\r
+ // Create TimeoutEvent for response\r
+ //\r
+ Status = gBS->CreateEvent (\r
+ EVT_TIMER,\r
+ TPL_CALLBACK,\r
+ NULL,\r
+ NULL,\r
+ &Event\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ goto ON_ERROR;\r
+ }\r
+ HttpIo->TimeoutEvent = Event;\r
+\r
return EFI_SUCCESS;\r
\r
ON_ERROR:\r
return EFI_SUCCESS;\r
\r
ON_ERROR:\r
if (Event != NULL) {\r
gBS->CloseEvent (Event);\r
}\r
if (Event != NULL) {\r
gBS->CloseEvent (Event);\r
}\r
+\r
+ Event = HttpIo->TimeoutEvent;\r
+ if (Event != NULL) {\r
+ gBS->CloseEvent (Event);\r
+ }\r
\r
Http = HttpIo->Http;\r
if (Http != NULL) {\r
\r
Http = HttpIo->Http;\r
if (Http != NULL) {\r
return EFI_INVALID_PARAMETER;\r
}\r
\r
return EFI_INVALID_PARAMETER;\r
}\r
\r
+ //\r
+ // Start the timer, and wait Timeout seconds to receive the header packet.\r
+ //\r
+ Status = gBS->SetTimer (HttpIo->TimeoutEvent, TimerRelative, HTTP_BOOT_RESPONSE_TIMEOUT * TICKS_PER_MS);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
//\r
// Queue the response token to HTTP instances.\r
//\r
//\r
// Queue the response token to HTTP instances.\r
//\r
);\r
\r
if (EFI_ERROR (Status)) {\r
);\r
\r
if (EFI_ERROR (Status)) {\r
+ gBS->SetTimer (HttpIo->TimeoutEvent, TimerCancel, 0);\r
return Status;\r
}\r
\r
//\r
// Poll the network until receive finish.\r
//\r
return Status;\r
}\r
\r
//\r
// Poll the network until receive finish.\r
//\r
- while (!HttpIo->IsRxDone) {\r
+ while (!HttpIo->IsRxDone && ((HttpIo->TimeoutEvent == NULL) || EFI_ERROR (gBS->CheckEvent (HttpIo->TimeoutEvent)))) {\r
Http->Poll (Http);\r
}\r
\r
Http->Poll (Http);\r
}\r
\r
+ gBS->SetTimer (HttpIo->TimeoutEvent, TimerCancel, 0);\r
+\r
+ if (!HttpIo->IsRxDone) {\r
+ //\r
+ // Timeout occurs, cancel the response token.\r
+ //\r
+ Http->Cancel (Http, &HttpIo->RspToken);\r
+ \r
+ Status = EFI_TIMEOUT;\r
+ \r
+ return Status;\r
+ } else {\r
+ HttpIo->IsRxDone = FALSE;\r
+ }\r
+\r
//\r
// Store the received data into the wrapper.\r
//\r
//\r
// Store the received data into the wrapper.\r
//\r
\r
BOOLEAN IsTxDone;\r
BOOLEAN IsRxDone;\r
\r
BOOLEAN IsTxDone;\r
BOOLEAN IsRxDone;\r
+\r
+ EFI_EVENT TimeoutEvent;\r