This library is used to share code between UEFI network stack modules.\r
It provides the helper routines to access TCP service.\r
\r
-Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>\r
-This program and the accompanying materials\r
-are licensed and made available under the terms and conditions of the BSD License\r
-which accompanies this distribution. The full text of the license may be found at<BR>\r
-http://opensource.org/licenses/bsd-license.php\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.<BR>\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
\r
**/\r
\r
#include <Library/MemoryAllocationLib.h>\r
#include <Library/BaseMemoryLib.h>\r
\r
-/**
- The common notify function associated with various TcpIo events. \r
-
- @param[in] Event The event signaled.
- @param[in] Context The context.
-
-**/
-VOID
-EFIAPI
+/**\r
+ The common notify function associated with various TcpIo events.\r
+\r
+ @param[in] Event The event signaled.\r
+ @param[in] Context The context.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
TcpIoCommonNotify (\r
- IN EFI_EVENT Event,
- IN VOID *Context
- )
+ IN EFI_EVENT Event,\r
+ IN VOID *Context\r
+ )\r
{\r
if ((Event == NULL) || (Context == NULL)) {\r
return ;\r
}\r
\r
- *((BOOLEAN *) Context) = TRUE;
+ *((BOOLEAN *) Context) = TRUE;\r
}\r
\r
-/**
+/**\r
The internal function for delay configuring TCP6 when IP6 driver is still in DAD.\r
-
- @param[in] Tcp6 The EFI_TCP6_PROTOCOL protocol instance.
- @param[in] Tcp6ConfigData The Tcp6 configuration data.
-
- @retval EFI_SUCCESS The operational settings successfully
- completed.
+\r
+ @param[in] Tcp6 The EFI_TCP6_PROTOCOL protocol instance.\r
+ @param[in] Tcp6ConfigData The Tcp6 configuration data.\r
+\r
+ @retval EFI_SUCCESS The operational settings successfully\r
+ completed.\r
@retval EFI_INVALID_PARAMETER One or more parameters are invalid.\r
@retval Others Failed to finish the operation.\r
\r
-**/
-EFI_STATUS
+**/\r
+EFI_STATUS\r
TcpIoGetMapping (\r
- IN EFI_TCP6_PROTOCOL *Tcp6,
- IN EFI_TCP6_CONFIG_DATA *Tcp6ConfigData
- )
-{
- EFI_STATUS Status;
- EFI_EVENT Event;
+ IN EFI_TCP6_PROTOCOL *Tcp6,\r
+ IN EFI_TCP6_CONFIG_DATA *Tcp6ConfigData\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_EVENT Event;\r
\r
if ((Tcp6 == NULL) || (Tcp6ConfigData == NULL)) {\r
return EFI_INVALID_PARAMETER;\r
}\r
\r
- Event = NULL;
- Status = gBS->CreateEvent (
- EVT_TIMER,
- TPL_CALLBACK,
- NULL,
- NULL,
- &Event
- );
- if (EFI_ERROR (Status)) {
- goto ON_EXIT;
- }
-
- Status = gBS->SetTimer (
- Event,
- TimerRelative,
+ Event = NULL;\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_EXIT;\r
+ }\r
+\r
+ Status = gBS->SetTimer (\r
+ Event,\r
+ TimerRelative,\r
TCP_GET_MAPPING_TIMEOUT\r
- );
-
- if (EFI_ERROR (Status)) {
- goto ON_EXIT;
- }
-
- while (EFI_ERROR (gBS->CheckEvent (Event))) {
-
- Tcp6->Poll (Tcp6);
-
- Status = Tcp6->Configure (Tcp6, Tcp6ConfigData);
-
- if (!EFI_ERROR (Status)) {
- break;
- }
- }
-
-ON_EXIT:
-
- if (Event != NULL) {
- gBS->CloseEvent (Event);
- }
-
- return Status;
+ );\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ goto ON_EXIT;\r
+ }\r
+\r
+ while (EFI_ERROR (gBS->CheckEvent (Event))) {\r
+\r
+ Tcp6->Poll (Tcp6);\r
+\r
+ Status = Tcp6->Configure (Tcp6, Tcp6ConfigData);\r
+\r
+ if (!EFI_ERROR (Status)) {\r
+ break;\r
+ }\r
+ }\r
+\r
+ON_EXIT:\r
+\r
+ if (Event != NULL) {\r
+ gBS->CloseEvent (Event);\r
+ }\r
+\r
+ return Status;\r
}\r
\r
/**\r
- Create a TCP socket with the specified configuration data. \r
+ Create a TCP socket with the specified configuration data.\r
\r
@param[in] Image The handle of the driver image.\r
@param[in] Controller The handle of the controller.\r
@param[in] TcpVersion The version of Tcp, TCP_VERSION_4 or TCP_VERSION_6.\r
@param[in] ConfigData The Tcp configuration data.\r
@param[out] TcpIo The TcpIo.\r
- \r
+\r
@retval EFI_SUCCESS The TCP socket is created and configured.\r
@retval EFI_INVALID_PARAMETER One or more parameters are invalid.\r
- @retval EFI_UNSUPPORTED One or more of the control options are not
+ @retval EFI_UNSUPPORTED One or more of the control options are not\r
supported in the implementation.\r
+ @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.\r
@retval Others Failed to create the TCP socket or configure it.\r
\r
**/\r
EFI_TCP6_CONFIG_DATA Tcp6ConfigData;\r
EFI_TCP6_ACCESS_POINT *AccessPoint6;\r
EFI_TCP6_PROTOCOL *Tcp6;\r
+ EFI_TCP4_RECEIVE_DATA *RxData;\r
\r
if ((Image == NULL) || (Controller == NULL) || (ConfigData == NULL) || (TcpIo == NULL)) {\r
return EFI_INVALID_PARAMETER;\r
\r
//\r
// Create the TCP child instance and get the TCP protocol.\r
- // \r
- Status = NetLibCreateServiceChild (
- Controller,
- Image,
+ //\r
+ Status = NetLibCreateServiceChild (\r
+ Controller,\r
+ Image,\r
ServiceBindingGuid,\r
&TcpIo->Handle\r
- );
- if (EFI_ERROR (Status)) {
- return Status;
- }
-
- Status = gBS->OpenProtocol (
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ Status = gBS->OpenProtocol (\r
TcpIo->Handle,\r
ProtocolGuid,\r
Interface,\r
- Image,
- Controller,
- EFI_OPEN_PROTOCOL_BY_DRIVER
- );
+ Image,\r
+ Controller,\r
+ EFI_OPEN_PROTOCOL_BY_DRIVER\r
+ );\r
if (EFI_ERROR (Status) || (*Interface == NULL)) {\r
- goto ON_ERROR;
+ goto ON_ERROR;\r
}\r
\r
if (TcpVersion == TCP_VERSION_4) {\r
} else {\r
Tcp6 = TcpIo->Tcp.Tcp6;\r
}\r
-
+\r
TcpIo->Image = Image;\r
TcpIo->Controller = Controller;\r
-
- //
- // Set the configuration parameters.
- //
- ControlOption.ReceiveBufferSize = 0x200000;
- ControlOption.SendBufferSize = 0x200000;
- ControlOption.MaxSynBackLog = 0;
- ControlOption.ConnectionTimeout = 0;
- ControlOption.DataRetries = 6;
- ControlOption.FinTimeout = 0;
- ControlOption.TimeWaitTimeout = 0;
- ControlOption.KeepAliveProbes = 4;
- ControlOption.KeepAliveTime = 0;
- ControlOption.KeepAliveInterval = 0;
- ControlOption.EnableNagle = FALSE;
- ControlOption.EnableTimeStamp = FALSE;
- ControlOption.EnableWindowScaling = TRUE;
- ControlOption.EnableSelectiveAck = FALSE;
- ControlOption.EnablePathMtuDiscovery = FALSE;
+\r
+ //\r
+ // Set the configuration parameters.\r
+ //\r
+ ControlOption.ReceiveBufferSize = 0x200000;\r
+ ControlOption.SendBufferSize = 0x200000;\r
+ ControlOption.MaxSynBackLog = 0;\r
+ ControlOption.ConnectionTimeout = 0;\r
+ ControlOption.DataRetries = 6;\r
+ ControlOption.FinTimeout = 0;\r
+ ControlOption.TimeWaitTimeout = 0;\r
+ ControlOption.KeepAliveProbes = 4;\r
+ ControlOption.KeepAliveTime = 0;\r
+ ControlOption.KeepAliveInterval = 0;\r
+ ControlOption.EnableNagle = FALSE;\r
+ ControlOption.EnableTimeStamp = FALSE;\r
+ ControlOption.EnableWindowScaling = TRUE;\r
+ ControlOption.EnableSelectiveAck = FALSE;\r
+ ControlOption.EnablePathMtuDiscovery = FALSE;\r
\r
if (TcpVersion == TCP_VERSION_4) {\r
Tcp4ConfigData.TypeOfService = 8;\r
}\r
}\r
\r
- //
- // Create events for variuos asynchronous operations.
+ //\r
+ // Create events for variuos asynchronous operations.\r
//\r
Status = gBS->CreateEvent (\r
- EVT_NOTIFY_SIGNAL,
- TPL_NOTIFY,
+ EVT_NOTIFY_SIGNAL,\r
+ TPL_NOTIFY,\r
TcpIoCommonNotify,\r
&TcpIo->IsConnDone,\r
&Event\r
- );
- if (EFI_ERROR (Status)) {
- goto ON_ERROR;
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ goto ON_ERROR;\r
}\r
\r
TcpIo->ConnToken.Tcp4Token.CompletionToken.Event = Event;\r
\r
- Status = gBS->CreateEvent (
- EVT_NOTIFY_SIGNAL,
- TPL_NOTIFY,
+ Status = gBS->CreateEvent (\r
+ EVT_NOTIFY_SIGNAL,\r
+ TPL_NOTIFY,\r
TcpIoCommonNotify,\r
&TcpIo->IsListenDone,\r
&Event\r
- );
- if (EFI_ERROR (Status)) {
- goto ON_ERROR;
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ goto ON_ERROR;\r
}\r
\r
TcpIo->ListenToken.Tcp4Token.CompletionToken.Event = Event;\r
\r
- Status = gBS->CreateEvent (
- EVT_NOTIFY_SIGNAL,
- TPL_NOTIFY,
+ Status = gBS->CreateEvent (\r
+ EVT_NOTIFY_SIGNAL,\r
+ TPL_NOTIFY,\r
TcpIoCommonNotify,\r
&TcpIo->IsTxDone,\r
&Event\r
- );
- if (EFI_ERROR (Status)) {
- goto ON_ERROR;
- }
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ goto ON_ERROR;\r
+ }\r
\r
TcpIo->TxToken.Tcp4Token.CompletionToken.Event = Event;\r
\r
\r
- Status = gBS->CreateEvent (
- EVT_NOTIFY_SIGNAL,
- TPL_NOTIFY,
+ Status = gBS->CreateEvent (\r
+ EVT_NOTIFY_SIGNAL,\r
+ TPL_NOTIFY,\r
TcpIoCommonNotify,\r
&TcpIo->IsRxDone,\r
&Event\r
- );
- if (EFI_ERROR (Status)) {
- goto ON_ERROR;
- }
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ goto ON_ERROR;\r
+ }\r
\r
TcpIo->RxToken.Tcp4Token.CompletionToken.Event = Event;\r
\r
- Status = gBS->CreateEvent (
- EVT_NOTIFY_SIGNAL,
- TPL_NOTIFY,
+ RxData = (EFI_TCP4_RECEIVE_DATA *) AllocateZeroPool (sizeof (EFI_TCP4_RECEIVE_DATA));\r
+ if (RxData == NULL) {\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ goto ON_ERROR;\r
+ }\r
+\r
+ TcpIo->RxToken.Tcp4Token.Packet.RxData = RxData;\r
+\r
+ Status = gBS->CreateEvent (\r
+ EVT_NOTIFY_SIGNAL,\r
+ TPL_NOTIFY,\r
TcpIoCommonNotify,\r
&TcpIo->IsCloseDone,\r
&Event\r
- );
- if (EFI_ERROR (Status)) {
- goto ON_ERROR;
- }
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ goto ON_ERROR;\r
+ }\r
\r
TcpIo->CloseToken.Tcp4Token.CompletionToken.Event = Event;\r
\r
\r
return EFI_SUCCESS;\r
-
-ON_ERROR:
+\r
+ON_ERROR:\r
\r
TcpIoDestroySocket (TcpIo);\r
-
+\r
return Status;\r
}\r
- \r
+\r
/**\r
- Destroy the socket. \r
+ Destroy the socket.\r
\r
@param[in] TcpIo The TcpIo which wraps the socket to be destroyed.\r
\r
gBS->CloseEvent (Event);\r
}\r
\r
+ if (TcpIo->RxToken.Tcp4Token.Packet.RxData != NULL) {\r
+ FreePool (TcpIo->RxToken.Tcp4Token.Packet.RxData);\r
+ }\r
+\r
Tcp4 = NULL;\r
Tcp6 = NULL;\r
\r
\r
if ((Tcp4 != NULL) || (Tcp6 != NULL)) {\r
\r
- gBS->CloseProtocol (
+ gBS->CloseProtocol (\r
TcpIo->Handle,\r
ProtocolGuid,\r
TcpIo->Image,\r
}\r
}\r
\r
- NetLibDestroyServiceChild (
+ NetLibDestroyServiceChild (\r
TcpIo->Controller,\r
TcpIo->Image,\r
ServiceBindingGuid,\r
Connect to the other endpoint of the TCP socket.\r
\r
@param[in, out] TcpIo The TcpIo wrapping the TCP socket.\r
- @param[in] Timeout The time to wait for connection done.\r
- \r
+ @param[in] Timeout The time to wait for connection done. Set to NULL for infinite wait.\r
+\r
@retval EFI_SUCCESS Connect to the other endpoint of the TCP socket\r
successfully.\r
@retval EFI_TIMEOUT Failed to connect to the other endpoint of the\r
EFIAPI\r
TcpIoConnect (\r
IN OUT TCP_IO *TcpIo,\r
- IN EFI_EVENT Timeout\r
+ IN EFI_EVENT Timeout OPTIONAL\r
)\r
{\r
EFI_TCP4_PROTOCOL *Tcp4;\r
return EFI_UNSUPPORTED;\r
}\r
\r
- if (EFI_ERROR (Status)) {
- return Status;
- }
-
- while (!TcpIo->IsConnDone && EFI_ERROR (gBS->CheckEvent (Timeout))) {\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ while (!TcpIo->IsConnDone && ((Timeout == NULL) || EFI_ERROR (gBS->CheckEvent (Timeout)))) {\r
if (TcpIo->TcpVersion == TCP_VERSION_4) {\r
Tcp4->Poll (Tcp4);\r
} else {\r
Tcp6->Poll (Tcp6);\r
}\r
- }
-
+ }\r
+\r
if (!TcpIo->IsConnDone) {\r
- Status = EFI_TIMEOUT;
+ if (TcpIo->TcpVersion == TCP_VERSION_4) {\r
+ Tcp4->Cancel (Tcp4, &TcpIo->ConnToken.Tcp4Token.CompletionToken);\r
+ } else {\r
+ Tcp6->Cancel (Tcp6, &TcpIo->ConnToken.Tcp6Token.CompletionToken);\r
+ }\r
+ Status = EFI_TIMEOUT;\r
} else {\r
Status = TcpIo->ConnToken.Tcp4Token.CompletionToken.Status;\r
}\r
-
+\r
return Status;\r
}\r
\r
Accept the incomding request from the other endpoint of the TCP socket.\r
\r
@param[in, out] TcpIo The TcpIo wrapping the TCP socket.\r
- @param[in] Timeout The time to wait for connection done.\r
+ @param[in] Timeout The time to wait for connection done. Set to NULL for infinite wait.\r
+\r
\r
- \r
@retval EFI_SUCCESS Connect to the other endpoint of the TCP socket\r
successfully.\r
@retval EFI_INVALID_PARAMETER One or more parameters are invalid.\r
supported in the implementation.\r
\r
@retval EFI_TIMEOUT Failed to connect to the other endpoint of the\r
- TCP socket in the specified time period. \r
+ TCP socket in the specified time period.\r
@retval Others Other errors as indicated.\r
\r
**/\r
EFIAPI\r
TcpIoAccept (\r
IN OUT TCP_IO *TcpIo,\r
- IN EFI_EVENT Timeout\r
+ IN EFI_EVENT Timeout OPTIONAL\r
)\r
{\r
EFI_STATUS Status;\r
return EFI_UNSUPPORTED;\r
}\r
\r
- if (EFI_ERROR (Status)) {
- return Status;
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
}\r
\r
- while (!TcpIo->IsListenDone && EFI_ERROR (gBS->CheckEvent (Timeout))) {\r
+ while (!TcpIo->IsListenDone && ((Timeout == NULL) || EFI_ERROR (gBS->CheckEvent (Timeout)))) {\r
if (TcpIo->TcpVersion == TCP_VERSION_4) {\r
Tcp4->Poll (Tcp4);\r
} else {\r
Tcp6->Poll (Tcp6);\r
}\r
- }
+ }\r
\r
if (!TcpIo->IsListenDone) {\r
- Status = EFI_TIMEOUT;
+ if (TcpIo->TcpVersion == TCP_VERSION_4) {\r
+ Tcp4->Cancel (Tcp4, &TcpIo->ListenToken.Tcp4Token.CompletionToken);\r
+ } else {\r
+ Tcp6->Cancel (Tcp6, &TcpIo->ListenToken.Tcp6Token.CompletionToken);\r
+ }\r
+ Status = EFI_TIMEOUT;\r
} else {\r
Status = TcpIo->ListenToken.Tcp4Token.CompletionToken.Status;\r
}\r
\r
- //
- // The new TCP instance handle created for the established connection is
- // in ListenToken.
- //
+ //\r
+ // The new TCP instance handle created for the established connection is\r
+ // in ListenToken.\r
+ //\r
if (!EFI_ERROR (Status)) {\r
if (TcpIo->TcpVersion == TCP_VERSION_4) {\r
ProtocolGuid = &gEfiTcp4ProtocolGuid;\r
} else {\r
ProtocolGuid = &gEfiTcp6ProtocolGuid;\r
}\r
- \r
- Status = gBS->OpenProtocol (
+\r
+ Status = gBS->OpenProtocol (\r
TcpIo->ListenToken.Tcp4Token.NewChildHandle,\r
ProtocolGuid,\r
(VOID **) (&TcpIo->NewTcp.Tcp4),\r
TcpIo->Image,\r
TcpIo->Controller,\r
- EFI_OPEN_PROTOCOL_BY_DRIVER
- );
-
- }
+ EFI_OPEN_PROTOCOL_BY_DRIVER\r
+ );\r
+\r
+ }\r
\r
return Status;\r
}\r
Tcp4 = NULL;\r
Tcp6 = NULL;\r
\r
- if (TcpIo->TcpVersion == TCP_VERSION_4) { \r
+ if (TcpIo->TcpVersion == TCP_VERSION_4) {\r
TcpIo->CloseToken.Tcp4Token.AbortOnClose = TRUE;\r
Tcp4 = TcpIo->Tcp.Tcp4;\r
Status = Tcp4->Close (Tcp4, &TcpIo->CloseToken.Tcp4Token);\r
return ;\r
}\r
\r
- if (EFI_ERROR (Status)) {
- return ;
- }
-
+ if (EFI_ERROR (Status)) {\r
+ return ;\r
+ }\r
+\r
while (!TcpIo->IsCloseDone) {\r
if (TcpIo->TcpVersion == TCP_VERSION_4) {\r
Tcp4->Poll (Tcp4);\r
}\r
}\r
\r
- \r
+\r
/**\r
Transmit the Packet to the other endpoint of the socket.\r
\r
@param[in] TcpIo The TcpIo wrapping the TCP socket.\r
@param[in] Packet The packet to transmit.\r
- \r
+\r
@retval EFI_SUCCESS The packet is trasmitted.\r
@retval EFI_INVALID_PARAMETER One or more parameters are invalid.\r
@retval EFI_UNSUPPORTED One or more of the control options are not\r
\r
if (TcpIo->TcpVersion == TCP_VERSION_4) {\r
\r
- Size = sizeof (EFI_TCP4_TRANSMIT_DATA) + \r
+ Size = sizeof (EFI_TCP4_TRANSMIT_DATA) +\r
(Packet->BlockOpNum - 1) * sizeof (EFI_TCP4_FRAGMENT_DATA);\r
} else if (TcpIo->TcpVersion == TCP_VERSION_6) {\r
Size = sizeof (EFI_TCP6_TRANSMIT_DATA) +\r
\r
Data = AllocatePool (Size);\r
if (Data == NULL) {\r
- return EFI_OUT_OF_RESOURCES;
+ return EFI_OUT_OF_RESOURCES;\r
}\r
\r
((EFI_TCP4_TRANSMIT_DATA *) Data)->Push = TRUE;\r
((EFI_TCP4_TRANSMIT_DATA *) Data)->Urgent = FALSE;\r
((EFI_TCP4_TRANSMIT_DATA *) Data)->DataLength = Packet->TotalSize;\r
\r
- //
- // Build the fragment table.
- //
+ //\r
+ // Build the fragment table.\r
+ //\r
((EFI_TCP4_TRANSMIT_DATA *) Data)->FragmentCount = Packet->BlockOpNum;\r
\r
NetbufBuildExt (\r
Tcp6 = NULL;\r
Status = EFI_DEVICE_ERROR;\r
\r
- //
- // Trasnmit the packet.
+ //\r
+ // Trasnmit the packet.\r
//\r
if (TcpIo->TcpVersion == TCP_VERSION_4) {\r
TcpIo->TxToken.Tcp4Token.Packet.TxData = (EFI_TCP4_TRANSMIT_DATA *) Data;\r
if (Tcp4 == NULL) {\r
goto ON_EXIT;\r
}\r
- \r
+\r
Status = Tcp4->Transmit (Tcp4, &TcpIo->TxToken.Tcp4Token);\r
} else {\r
TcpIo->TxToken.Tcp6Token.Packet.TxData = (EFI_TCP6_TRANSMIT_DATA *) Data;\r
Status = Tcp6->Transmit (Tcp6, &TcpIo->TxToken.Tcp6Token);\r
}\r
\r
- if (EFI_ERROR (Status)) {
- goto ON_EXIT;
- }
-
+ if (EFI_ERROR (Status)) {\r
+ goto ON_EXIT;\r
+ }\r
+\r
while (!TcpIo->IsTxDone) {\r
if (TcpIo->TcpVersion == TCP_VERSION_4) {\r
Tcp4->Poll (Tcp4);\r
} else {\r
Tcp6->Poll (Tcp6);\r
}\r
- }
-
+ }\r
+\r
TcpIo->IsTxDone = FALSE;\r
Status = TcpIo->TxToken.Tcp4Token.CompletionToken.Status;\r
\r
-ON_EXIT:
-
+ON_EXIT:\r
+\r
FreePool (Data);\r
-
+\r
return Status;\r
}\r
\r
@param[in] Packet The buffer to hold the data copy from the socket rx buffer.\r
@param[in] AsyncMode Is this receive asyncronous or not.\r
@param[in] Timeout The time to wait for receiving the amount of data the Packet\r
- can hold.\r
+ can hold. Set to NULL for infinite wait.\r
\r
@retval EFI_SUCCESS The required amount of data is received from the socket.\r
@retval EFI_INVALID_PARAMETER One or more parameters are invalid.\r
IN OUT TCP_IO *TcpIo,\r
IN NET_BUF *Packet,\r
IN BOOLEAN AsyncMode,\r
- IN EFI_EVENT Timeout\r
+ IN EFI_EVENT Timeout OPTIONAL\r
)\r
{\r
EFI_TCP4_PROTOCOL *Tcp4;\r
EFI_TCP6_PROTOCOL *Tcp6;\r
- EFI_TCP4_RECEIVE_DATA RxData;\r
+ EFI_TCP4_RECEIVE_DATA *RxData;\r
EFI_STATUS Status;\r
NET_FRAGMENT *Fragment;\r
UINT32 FragmentCount;\r
return EFI_INVALID_PARAMETER;\r
}\r
\r
+ RxData = TcpIo->RxToken.Tcp4Token.Packet.RxData;\r
+ if (RxData == NULL) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
Tcp4 = NULL;\r
Tcp6 = NULL;\r
\r
return EFI_DEVICE_ERROR;\r
}\r
\r
- TcpIo->RxToken.Tcp4Token.Packet.RxData = &RxData;\r
-\r
} else if (TcpIo->TcpVersion == TCP_VERSION_6) {\r
Tcp6 = TcpIo->Tcp.Tcp6;\r
\r
}\r
\r
if (Tcp6 == NULL) {\r
- return EFI_DEVICE_ERROR; \r
+ return EFI_DEVICE_ERROR;\r
}\r
\r
- TcpIo->RxToken.Tcp6Token.Packet.RxData = (EFI_TCP6_RECEIVE_DATA *) &RxData;\r
-\r
} else {\r
return EFI_UNSUPPORTED;\r
}\r
\r
- FragmentCount = Packet->BlockOpNum;
- Fragment = AllocatePool (FragmentCount * sizeof (NET_FRAGMENT));
- if (Fragment == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
- //
- // Build the fragment table.
- //
- NetbufBuildExt (Packet, Fragment, &FragmentCount);
+ FragmentCount = Packet->BlockOpNum;\r
+ Fragment = AllocatePool (FragmentCount * sizeof (NET_FRAGMENT));\r
+ if (Fragment == NULL) {\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ goto ON_EXIT;\r
+ }\r
+ //\r
+ // Build the fragment table.\r
+ //\r
+ NetbufBuildExt (Packet, Fragment, &FragmentCount);\r
\r
- RxData.FragmentCount = 1;\r
+ RxData->FragmentCount = 1;\r
CurrentFragment = 0;\r
- Status = EFI_SUCCESS;
-
- while (CurrentFragment < FragmentCount) {
- RxData.DataLength = Fragment[CurrentFragment].Len;
- RxData.FragmentTable[0].FragmentLength = Fragment[CurrentFragment].Len;
- RxData.FragmentTable[0].FragmentBuffer = Fragment[CurrentFragment].Bulk;
+ Status = EFI_SUCCESS;\r
+\r
+ while (CurrentFragment < FragmentCount) {\r
+ RxData->DataLength = Fragment[CurrentFragment].Len;\r
+ RxData->FragmentTable[0].FragmentLength = Fragment[CurrentFragment].Len;\r
+ RxData->FragmentTable[0].FragmentBuffer = Fragment[CurrentFragment].Bulk;\r
\r
if (TcpIo->TcpVersion == TCP_VERSION_4) {\r
Status = Tcp4->Receive (Tcp4, &TcpIo->RxToken.Tcp4Token);\r
} else {\r
Status = Tcp6->Receive (Tcp6, &TcpIo->RxToken.Tcp6Token);\r
}\r
- \r
- if (EFI_ERROR (Status)) {
- goto ON_EXIT;
- }
- \r
+\r
+ if (EFI_ERROR (Status)) {\r
+ goto ON_EXIT;\r
+ }\r
+\r
while (!TcpIo->IsRxDone && ((Timeout == NULL) || EFI_ERROR (gBS->CheckEvent (Timeout)))) {\r
//\r
// Poll until some data is received or an error occurs.\r
Tcp6->Poll (Tcp6);\r
}\r
}\r
-
+\r
if (!TcpIo->IsRxDone) {\r
- //
- // Timeout occurs, cancel the receive request.
- //
+ //\r
+ // Timeout occurs, cancel the receive request.\r
+ //\r
if (TcpIo->TcpVersion == TCP_VERSION_4) {\r
Tcp4->Cancel (Tcp4, &TcpIo->RxToken.Tcp4Token.CompletionToken);\r
} else {\r
Tcp6->Cancel (Tcp6, &TcpIo->RxToken.Tcp6Token.CompletionToken);\r
}\r
-
- Status = EFI_TIMEOUT;
- goto ON_EXIT;
- } else {
+\r
+ Status = EFI_TIMEOUT;\r
+ goto ON_EXIT;\r
+ } else {\r
TcpIo->IsRxDone = FALSE;\r
}\r
\r
Status = TcpIo->RxToken.Tcp4Token.CompletionToken.Status;\r
\r
if (EFI_ERROR (Status)) {\r
- goto ON_EXIT;
- }
-
- Fragment[CurrentFragment].Len -= RxData.FragmentTable[0].FragmentLength;
- if (Fragment[CurrentFragment].Len == 0) {
- CurrentFragment++;
- } else {
- Fragment[CurrentFragment].Bulk += RxData.FragmentTable[0].FragmentLength;
- }
- }
-
-ON_EXIT:
+ goto ON_EXIT;\r
+ }\r
\r
- if (TcpIo->TcpVersion == TCP_VERSION_4) {\r
- TcpIo->RxToken.Tcp4Token.Packet.RxData = NULL;\r
- } else {\r
- TcpIo->RxToken.Tcp6Token.Packet.RxData = NULL;\r
+ Fragment[CurrentFragment].Len -= RxData->FragmentTable[0].FragmentLength;\r
+ if (Fragment[CurrentFragment].Len == 0) {\r
+ CurrentFragment++;\r
+ } else {\r
+ Fragment[CurrentFragment].Bulk += RxData->FragmentTable[0].FragmentLength;\r
+ }\r
+ }\r
+\r
+ON_EXIT:\r
+\r
+ if (Fragment != NULL) {\r
+ FreePool (Fragment);\r
}\r
\r
- FreePool (Fragment);\r
-
return Status;\r
}\r