NetworkPkg:Enable Http Boot over Ipv6 stack
Add new features to support Http boot over ipv6 stack. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Zhang Lubo <lubo.zhang@intel.com> Reviewed-by: Fu Siyuan <siyuan.fu@intel.com> Reviewed-by: Ye Ting <ting.ye@intel.com> Reviewed-by: Wu Jiaxin <jiaxin.wu@intel.com> git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@18743 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
@@ -194,11 +194,11 @@ Exit:
|
||||
Dns4->Configure (Dns4, NULL);
|
||||
|
||||
gBS->CloseProtocol (
|
||||
Dns4Handle,
|
||||
&gEfiDns4ProtocolGuid,
|
||||
Service->ImageHandle,
|
||||
Service->ControllerHandle
|
||||
);
|
||||
Dns4Handle,
|
||||
&gEfiDns4ProtocolGuid,
|
||||
Service->ImageHandle,
|
||||
Service->ControllerHandle
|
||||
);
|
||||
}
|
||||
|
||||
if (Dns4Handle != NULL) {
|
||||
@@ -216,3 +216,200 @@ Exit:
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
Retrieve the host address using the EFI_DNS6_PROTOCOL.
|
||||
|
||||
@param[in] HttpInstance Pointer to HTTP_PROTOCOL instance.
|
||||
@param[in] HostName Pointer to buffer containing hostname.
|
||||
@param[out] IpAddress On output, pointer to buffer containing IPv6 address.
|
||||
|
||||
@retval EFI_SUCCESS Operation succeeded.
|
||||
@retval EFI_OUT_OF_RESOURCES Failed to allocate needed resources.
|
||||
@retval EFI_DEVICE_ERROR An unexpected network error occurred.
|
||||
@retval Others Other errors as indicated.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
HttpDns6 (
|
||||
IN HTTP_PROTOCOL *HttpInstance,
|
||||
IN CHAR16 *HostName,
|
||||
OUT EFI_IPv6_ADDRESS *IpAddress
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
HTTP_SERVICE *Service;
|
||||
EFI_DNS6_PROTOCOL *Dns6;
|
||||
EFI_DNS6_CONFIG_DATA Dns6ConfigData;
|
||||
EFI_DNS6_COMPLETION_TOKEN Token;
|
||||
EFI_HANDLE Dns6Handle;
|
||||
EFI_IP6_CONFIG_PROTOCOL *Ip6Config;
|
||||
EFI_IPv6_ADDRESS *DnsServerList;
|
||||
UINTN DnsServerListCount;
|
||||
UINTN DataSize;
|
||||
BOOLEAN IsDone;
|
||||
|
||||
|
||||
Service = HttpInstance->Service;
|
||||
ASSERT (Service != NULL);
|
||||
|
||||
DnsServerList = NULL;
|
||||
DnsServerListCount = 0;
|
||||
Dns6 = NULL;
|
||||
Dns6Handle = NULL;
|
||||
ZeroMem (&Token, sizeof (EFI_DNS6_COMPLETION_TOKEN));
|
||||
|
||||
//
|
||||
// Get DNS server list from EFI IPv6 Configuration protocol.
|
||||
//
|
||||
Status = gBS->HandleProtocol (Service->ControllerHandle, &gEfiIp6ConfigProtocolGuid, (VOID **) &Ip6Config);
|
||||
if (!EFI_ERROR (Status)) {
|
||||
//
|
||||
// Get the required size.
|
||||
//
|
||||
DataSize = 0;
|
||||
Status = Ip6Config->GetData (Ip6Config, Ip6ConfigDataTypeDnsServer, &DataSize, NULL);
|
||||
if (Status == EFI_BUFFER_TOO_SMALL) {
|
||||
DnsServerList = AllocatePool (DataSize);
|
||||
if (DnsServerList == NULL) {
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
Status = Ip6Config->GetData (Ip6Config, Ip6ConfigDataTypeDnsServer, &DataSize, DnsServerList);
|
||||
if (EFI_ERROR (Status)) {
|
||||
FreePool (DnsServerList);
|
||||
DnsServerList = NULL;
|
||||
} else {
|
||||
DnsServerListCount = DataSize / sizeof (EFI_IPv6_ADDRESS);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Create a DNSv6 child instance and get the protocol.
|
||||
//
|
||||
Status = NetLibCreateServiceChild (
|
||||
Service->ControllerHandle,
|
||||
Service->ImageHandle,
|
||||
&gEfiDns6ServiceBindingProtocolGuid,
|
||||
&Dns6Handle
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
Status = gBS->OpenProtocol (
|
||||
Dns6Handle,
|
||||
&gEfiDns6ProtocolGuid,
|
||||
(VOID **) &Dns6,
|
||||
Service->ImageHandle,
|
||||
Service->ControllerHandle,
|
||||
EFI_OPEN_PROTOCOL_BY_DRIVER
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
//
|
||||
// Configure DNS6 instance for the DNS server address and protocol.
|
||||
//
|
||||
ZeroMem (&Dns6ConfigData, sizeof (EFI_DNS6_CONFIG_DATA));
|
||||
Dns6ConfigData.DnsServerCount = (UINT32)DnsServerListCount;
|
||||
Dns6ConfigData.DnsServerList = DnsServerList;
|
||||
Dns6ConfigData.EnableDnsCache = TRUE;
|
||||
Dns6ConfigData.Protocol = EFI_IP_PROTO_UDP;
|
||||
IP6_COPY_ADDRESS (&Dns6ConfigData.StationIp, &HttpInstance->Ipv6Node.LocalAddress);
|
||||
Status = Dns6->Configure (
|
||||
Dns6,
|
||||
&Dns6ConfigData
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
Token.Status = EFI_NOT_READY;
|
||||
IsDone = FALSE;
|
||||
//
|
||||
// Create event to set the IsDone flag when name resolution is finished.
|
||||
//
|
||||
Status = gBS->CreateEvent (
|
||||
EVT_NOTIFY_SIGNAL,
|
||||
TPL_NOTIFY,
|
||||
HttpCommonNotify,
|
||||
&IsDone,
|
||||
&Token.Event
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
//
|
||||
// Start asynchronous name resolution.
|
||||
//
|
||||
Status = Dns6->HostNameToIp (Dns6, HostName, &Token);
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
while (!IsDone) {
|
||||
Dns6->Poll (Dns6);
|
||||
}
|
||||
|
||||
//
|
||||
// Name resolution is done, check result.
|
||||
//
|
||||
Status = Token.Status;
|
||||
if (!EFI_ERROR (Status)) {
|
||||
if (Token.RspData.H2AData == NULL) {
|
||||
Status = EFI_DEVICE_ERROR;
|
||||
goto Exit;
|
||||
}
|
||||
if (Token.RspData.H2AData->IpCount == 0 || Token.RspData.H2AData->IpList == NULL) {
|
||||
Status = EFI_DEVICE_ERROR;
|
||||
goto Exit;
|
||||
}
|
||||
//
|
||||
// We just return the first IPv6 address from DNS protocol.
|
||||
//
|
||||
IP6_COPY_ADDRESS (IpAddress, Token.RspData.H2AData->IpList);
|
||||
Status = EFI_SUCCESS;
|
||||
}
|
||||
|
||||
Exit:
|
||||
|
||||
if (Token.Event != NULL) {
|
||||
gBS->CloseEvent (Token.Event);
|
||||
}
|
||||
if (Token.RspData.H2AData != NULL) {
|
||||
if (Token.RspData.H2AData->IpList != NULL) {
|
||||
FreePool (Token.RspData.H2AData->IpList);
|
||||
}
|
||||
FreePool (Token.RspData.H2AData);
|
||||
}
|
||||
|
||||
if (Dns6 != NULL) {
|
||||
Dns6->Configure (Dns6, NULL);
|
||||
|
||||
gBS->CloseProtocol (
|
||||
Dns6Handle,
|
||||
&gEfiDns6ProtocolGuid,
|
||||
Service->ImageHandle,
|
||||
Service->ControllerHandle
|
||||
);
|
||||
}
|
||||
|
||||
if (Dns6Handle != NULL) {
|
||||
NetLibDestroyServiceChild (
|
||||
Service->ControllerHandle,
|
||||
Service->ImageHandle,
|
||||
&gEfiDns6ServiceBindingProtocolGuid,
|
||||
Dns6Handle
|
||||
);
|
||||
}
|
||||
|
||||
if (DnsServerList != NULL) {
|
||||
FreePool (DnsServerList);
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
@@ -35,4 +35,24 @@ HttpDns4 (
|
||||
OUT EFI_IPv4_ADDRESS *IpAddress
|
||||
);
|
||||
|
||||
/**
|
||||
Retrieve the host address using the EFI_DNS6_PROTOCOL.
|
||||
|
||||
@param[in] HttpInstance Pointer to HTTP_PROTOCOL instance.
|
||||
@param[in] HostName Pointer to buffer containing hostname.
|
||||
@param[out] IpAddress On output, pointer to buffer containing IPv6 address.
|
||||
|
||||
@retval EFI_SUCCESS Operation succeeded.
|
||||
@retval EFI_OUT_OF_RESOURCES Failed to allocate needed resources.
|
||||
@retval EFI_DEVICE_ERROR An unexpected network error occurred.
|
||||
@retval Others Other errors as indicated.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
HttpDns6 (
|
||||
IN HTTP_PROTOCOL *HttpInstance,
|
||||
IN CHAR16 *HostName,
|
||||
OUT EFI_IPv6_ADDRESS *IpAddress
|
||||
);
|
||||
|
||||
#endif
|
@@ -20,15 +20,25 @@ EFI_HTTP_UTILITIES_PROTOCOL *mHttpUtilities = NULL;
|
||||
///
|
||||
/// Driver Binding Protocol instance
|
||||
///
|
||||
EFI_DRIVER_BINDING_PROTOCOL gHttpDxeDriverBinding = {
|
||||
HttpDxeDriverBindingSupported,
|
||||
HttpDxeDriverBindingStart,
|
||||
HttpDxeDriverBindingStop,
|
||||
EFI_DRIVER_BINDING_PROTOCOL gHttpDxeIp4DriverBinding = {
|
||||
HttpDxeIp4DriverBindingSupported,
|
||||
HttpDxeIp4DriverBindingStart,
|
||||
HttpDxeIp4DriverBindingStop,
|
||||
HTTP_DRIVER_VERSION,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
EFI_DRIVER_BINDING_PROTOCOL gHttpDxeIp6DriverBinding = {
|
||||
HttpDxeIp6DriverBindingSupported,
|
||||
HttpDxeIp6DriverBindingStart,
|
||||
HttpDxeIp6DriverBindingStop,
|
||||
HTTP_DRIVER_VERSION,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
Create a HTTP driver service binding private instance.
|
||||
|
||||
@@ -73,33 +83,59 @@ HttpCreateService (
|
||||
/**
|
||||
Release all the resource used the HTTP service binding instance.
|
||||
|
||||
@param HttpService The HTTP private instance.
|
||||
|
||||
@param[in] HttpService The HTTP private instance.
|
||||
@param[in] UsingIpv6 Indicate use TCP4 protocol or TCP6 protocol.
|
||||
if TRUE, use Tcp6 protocol.
|
||||
if FALSE, use Tcp4 protocl.
|
||||
**/
|
||||
VOID
|
||||
HttpCleanService (
|
||||
IN HTTP_SERVICE *HttpService
|
||||
IN HTTP_SERVICE *HttpService,
|
||||
IN BOOLEAN UsingIpv6
|
||||
)
|
||||
{
|
||||
{
|
||||
|
||||
if (HttpService == NULL) {
|
||||
return ;
|
||||
}
|
||||
|
||||
if (HttpService->TcpChildHandle != NULL) {
|
||||
gBS->CloseProtocol (
|
||||
HttpService->TcpChildHandle,
|
||||
&gEfiTcp4ProtocolGuid,
|
||||
HttpService->ImageHandle,
|
||||
HttpService->ControllerHandle
|
||||
);
|
||||
|
||||
NetLibDestroyServiceChild (
|
||||
HttpService->ControllerHandle,
|
||||
HttpService->ImageHandle,
|
||||
&gEfiTcp4ServiceBindingProtocolGuid,
|
||||
HttpService->TcpChildHandle
|
||||
);
|
||||
if (!UsingIpv6) {
|
||||
if (HttpService->Tcp4ChildHandle != NULL) {
|
||||
gBS->CloseProtocol (
|
||||
HttpService->Tcp4ChildHandle,
|
||||
&gEfiTcp4ProtocolGuid,
|
||||
HttpService->ImageHandle,
|
||||
HttpService->ControllerHandle
|
||||
);
|
||||
|
||||
NetLibDestroyServiceChild (
|
||||
HttpService->ControllerHandle,
|
||||
HttpService->ImageHandle,
|
||||
&gEfiTcp4ServiceBindingProtocolGuid,
|
||||
HttpService->Tcp4ChildHandle
|
||||
);
|
||||
|
||||
HttpService->Tcp4ChildHandle = NULL;
|
||||
}
|
||||
} else {
|
||||
if (HttpService->Tcp6ChildHandle != NULL) {
|
||||
gBS->CloseProtocol (
|
||||
HttpService->Tcp6ChildHandle,
|
||||
&gEfiTcp6ProtocolGuid,
|
||||
HttpService->ImageHandle,
|
||||
HttpService->ControllerHandle
|
||||
);
|
||||
|
||||
NetLibDestroyServiceChild (
|
||||
HttpService->ControllerHandle,
|
||||
HttpService->ImageHandle,
|
||||
&gEfiTcp6ServiceBindingProtocolGuid,
|
||||
HttpService->Tcp6ChildHandle
|
||||
);
|
||||
|
||||
HttpService->Tcp6ChildHandle = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -107,7 +143,7 @@ HttpCleanService (
|
||||
in the system.
|
||||
|
||||
@param[in] Event Not used.
|
||||
@param[in] Context The pointer to the IP4 config2 instance data.
|
||||
@param[in] Context The pointer to the IP4 config2 instance data or IP6 Config instance data.
|
||||
|
||||
**/
|
||||
VOID
|
||||
@@ -122,7 +158,7 @@ HttpUtilitiesInstalledCallback (
|
||||
NULL,
|
||||
(VOID **) &mHttpUtilities
|
||||
);
|
||||
|
||||
|
||||
//
|
||||
// Close the event if Http utilities protocol is loacted.
|
||||
//
|
||||
@@ -150,6 +186,7 @@ HttpDxeDriverEntryPoint (
|
||||
IN EFI_SYSTEM_TABLE *SystemTable
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
VOID *Registration;
|
||||
|
||||
gBS->LocateProtocol (
|
||||
@@ -174,14 +211,39 @@ HttpDxeDriverEntryPoint (
|
||||
//
|
||||
// Install UEFI Driver Model protocol(s).
|
||||
//
|
||||
return EfiLibInstallDriverBindingComponentName2 (
|
||||
ImageHandle,
|
||||
SystemTable,
|
||||
&gHttpDxeDriverBinding,
|
||||
Status = EfiLibInstallDriverBindingComponentName2 (
|
||||
ImageHandle,
|
||||
SystemTable,
|
||||
&gHttpDxeIp4DriverBinding,
|
||||
ImageHandle,
|
||||
&gHttpDxeComponentName,
|
||||
&gHttpDxeComponentName2
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
Status = EfiLibInstallDriverBindingComponentName2 (
|
||||
ImageHandle,
|
||||
SystemTable,
|
||||
&gHttpDxeIp6DriverBinding,
|
||||
NULL,
|
||||
&gHttpDxeComponentName,
|
||||
&gHttpDxeComponentName2
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
gBS->UninstallMultipleProtocolInterfaces (
|
||||
ImageHandle,
|
||||
&gEfiDriverBindingProtocolGuid,
|
||||
&gHttpDxeIp4DriverBinding,
|
||||
&gEfiComponentName2ProtocolGuid,
|
||||
&gHttpDxeComponentName2,
|
||||
&gEfiComponentNameProtocolGuid,
|
||||
&gHttpDxeComponentName,
|
||||
&gHttpDxeComponentName2
|
||||
NULL
|
||||
);
|
||||
}
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -223,6 +285,309 @@ HttpDestroyChildEntryInHandleBuffer (
|
||||
return ServiceBinding->DestroyChild (ServiceBinding, HttpInstance->Handle);
|
||||
}
|
||||
|
||||
/**
|
||||
Test to see if this driver supports ControllerHandle. This is the worker function for
|
||||
HttpDxeIp4(6)DriverBindingSupported.
|
||||
|
||||
@param[in] This The pointer to the driver binding protocol.
|
||||
@param[in] ControllerHandle The handle of device to be tested.
|
||||
@param[in] RemainingDevicePath Optional parameter used to pick a specific child
|
||||
device to be started.
|
||||
@param[in] IpVersion IP_VERSION_4 or IP_VERSION_6.
|
||||
|
||||
@retval EFI_SUCCESS This driver supports this device.
|
||||
@retval EFI_UNSUPPORTED This driver does not support this device.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
HttpDxeSupported (
|
||||
IN EFI_DRIVER_BINDING_PROTOCOL *This,
|
||||
IN EFI_HANDLE ControllerHandle,
|
||||
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL,
|
||||
IN UINT8 IpVersion
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_GUID *TcpServiceBindingProtocolGuid;
|
||||
|
||||
if (IpVersion == IP_VERSION_4) {
|
||||
TcpServiceBindingProtocolGuid = &gEfiTcp4ServiceBindingProtocolGuid;
|
||||
} else {
|
||||
TcpServiceBindingProtocolGuid = &gEfiTcp6ServiceBindingProtocolGuid;
|
||||
}
|
||||
|
||||
Status = gBS->OpenProtocol (
|
||||
ControllerHandle,
|
||||
TcpServiceBindingProtocolGuid,
|
||||
NULL,
|
||||
This->DriverBindingHandle,
|
||||
ControllerHandle,
|
||||
EFI_OPEN_PROTOCOL_TEST_PROTOCOL
|
||||
);
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
Start this driver on ControllerHandle. This is the worker function for
|
||||
HttpDxeIp4(6)DriverBindingStart.
|
||||
|
||||
@param[in] This The pointer to the driver binding protocol.
|
||||
@param[in] ControllerHandle The handle of device to be started.
|
||||
@param[in] RemainingDevicePath Optional parameter used to pick a specific child
|
||||
device to be started.
|
||||
@param[in] IpVersion IP_VERSION_4 or IP_VERSION_6.
|
||||
|
||||
|
||||
@retval EFI_SUCCESS This driver is installed to ControllerHandle.
|
||||
@retval EFI_ALREADY_STARTED This driver is already running on ControllerHandle.
|
||||
@retval other This driver does not support this device.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
HttpDxeStart (
|
||||
IN EFI_DRIVER_BINDING_PROTOCOL *This,
|
||||
IN EFI_HANDLE ControllerHandle,
|
||||
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL,
|
||||
IN UINT8 IpVersion
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
|
||||
HTTP_SERVICE *HttpService;
|
||||
VOID *Interface;
|
||||
BOOLEAN UsingIpv6;
|
||||
|
||||
UsingIpv6 = FALSE;
|
||||
|
||||
//
|
||||
// Test for the Http service binding protocol
|
||||
//
|
||||
Status = gBS->OpenProtocol (
|
||||
ControllerHandle,
|
||||
&gEfiHttpServiceBindingProtocolGuid,
|
||||
(VOID **) &ServiceBinding,
|
||||
This->DriverBindingHandle,
|
||||
ControllerHandle,
|
||||
EFI_OPEN_PROTOCOL_GET_PROTOCOL
|
||||
);
|
||||
|
||||
if (!EFI_ERROR (Status)) {
|
||||
HttpService = HTTP_SERVICE_FROM_PROTOCOL (ServiceBinding);
|
||||
} else {
|
||||
Status = HttpCreateService (ControllerHandle, This->DriverBindingHandle, &HttpService);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
ASSERT (HttpService != NULL);
|
||||
|
||||
//
|
||||
// Install the HttpServiceBinding Protocol onto Controller
|
||||
//
|
||||
Status = gBS->InstallMultipleProtocolInterfaces (
|
||||
&ControllerHandle,
|
||||
&gEfiHttpServiceBindingProtocolGuid,
|
||||
&HttpService->ServiceBinding,
|
||||
NULL
|
||||
);
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto ON_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
if (IpVersion == IP_VERSION_4) {
|
||||
|
||||
if (HttpService->Tcp4ChildHandle == NULL) {
|
||||
//
|
||||
// Create a TCP4 child instance, but do not configure it. This will establish the parent-child relationship.
|
||||
//
|
||||
Status = NetLibCreateServiceChild (
|
||||
ControllerHandle,
|
||||
This->DriverBindingHandle,
|
||||
&gEfiTcp4ServiceBindingProtocolGuid,
|
||||
&HttpService->Tcp4ChildHandle
|
||||
);
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto ON_ERROR;
|
||||
}
|
||||
|
||||
Status = gBS->OpenProtocol (
|
||||
HttpService->Tcp4ChildHandle,
|
||||
&gEfiTcp4ProtocolGuid,
|
||||
&Interface,
|
||||
This->DriverBindingHandle,
|
||||
ControllerHandle,
|
||||
EFI_OPEN_PROTOCOL_BY_DRIVER
|
||||
);
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto ON_ERROR;
|
||||
}
|
||||
|
||||
} else {
|
||||
return EFI_ALREADY_STARTED;
|
||||
}
|
||||
|
||||
} else {
|
||||
UsingIpv6 = TRUE;
|
||||
|
||||
if (HttpService->Tcp6ChildHandle == NULL) {
|
||||
//
|
||||
// Create a TCP6 child instance, but do not configure it. This will establish the parent-child relationship.
|
||||
//
|
||||
Status = NetLibCreateServiceChild (
|
||||
ControllerHandle,
|
||||
This->DriverBindingHandle,
|
||||
&gEfiTcp6ServiceBindingProtocolGuid,
|
||||
&HttpService->Tcp6ChildHandle
|
||||
);
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto ON_ERROR;
|
||||
}
|
||||
|
||||
Status = gBS->OpenProtocol (
|
||||
HttpService->Tcp6ChildHandle,
|
||||
&gEfiTcp6ProtocolGuid,
|
||||
&Interface,
|
||||
This->DriverBindingHandle,
|
||||
ControllerHandle,
|
||||
EFI_OPEN_PROTOCOL_BY_DRIVER
|
||||
);
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto ON_ERROR;
|
||||
}
|
||||
|
||||
} else {
|
||||
return EFI_ALREADY_STARTED;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
|
||||
ON_ERROR:
|
||||
|
||||
if (HttpService != NULL) {
|
||||
HttpCleanService (HttpService, UsingIpv6);
|
||||
if (HttpService->Tcp4ChildHandle == NULL && HttpService->Tcp6ChildHandle == NULL) {
|
||||
FreePool (HttpService);
|
||||
}
|
||||
}
|
||||
|
||||
return Status;
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
Stop this driver on ControllerHandle. This is the worker function for
|
||||
HttpDxeIp4(6)DriverBindingStop.
|
||||
|
||||
@param[in] This Protocol instance pointer.
|
||||
@param[in] ControllerHandle Handle of device to stop driver on.
|
||||
@param[in] NumberOfChildren Number of Handles in ChildHandleBuffer. If number of
|
||||
children is zero stop the entire bus driver.
|
||||
@param[in] ChildHandleBuffer List of Child Handles to Stop.
|
||||
@param[in] IpVersion IP_VERSION_4 or IP_VERSION_6.
|
||||
|
||||
@retval EFI_SUCCESS This driver was removed ControllerHandle.
|
||||
@retval EFI_DEVICE_ERROR An unexpected system or network error occurred.
|
||||
@retval Others This driver was not removed from this device
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
HttpDxeStop (
|
||||
IN EFI_DRIVER_BINDING_PROTOCOL *This,
|
||||
IN EFI_HANDLE ControllerHandle,
|
||||
IN UINTN NumberOfChildren,
|
||||
IN EFI_HANDLE *ChildHandleBuffer,
|
||||
IN UINT8 IpVersion
|
||||
)
|
||||
{
|
||||
EFI_HANDLE NicHandle;
|
||||
EFI_STATUS Status;
|
||||
EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
|
||||
HTTP_SERVICE *HttpService;
|
||||
LIST_ENTRY *List;
|
||||
HTTP_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT Context;
|
||||
BOOLEAN UsingIpv6;
|
||||
|
||||
//
|
||||
// HTTP driver opens TCP4(6) child, So, Controller is a TCP4(6)
|
||||
// child handle. Locate the Nic handle first. Then get the
|
||||
// HTTP private data back.
|
||||
//
|
||||
if (IpVersion == IP_VERSION_4) {
|
||||
UsingIpv6 = FALSE;
|
||||
NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiTcp4ProtocolGuid);
|
||||
} else {
|
||||
UsingIpv6 = TRUE;
|
||||
NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiTcp6ProtocolGuid);
|
||||
}
|
||||
|
||||
if (NicHandle == NULL) {
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
Status = gBS->OpenProtocol (
|
||||
NicHandle,
|
||||
&gEfiHttpServiceBindingProtocolGuid,
|
||||
(VOID **) &ServiceBinding,
|
||||
This->DriverBindingHandle,
|
||||
NicHandle,
|
||||
EFI_OPEN_PROTOCOL_GET_PROTOCOL
|
||||
);
|
||||
|
||||
if (!EFI_ERROR (Status)) {
|
||||
|
||||
HttpService = HTTP_SERVICE_FROM_PROTOCOL (ServiceBinding);
|
||||
|
||||
if (NumberOfChildren != 0) {
|
||||
//
|
||||
// Destroy the HTTP child instance in ChildHandleBuffer.
|
||||
//
|
||||
List = &HttpService->ChildrenList;
|
||||
Context.ServiceBinding = ServiceBinding;
|
||||
Context.NumberOfChildren = NumberOfChildren;
|
||||
Context.ChildHandleBuffer = ChildHandleBuffer;
|
||||
Status = NetDestroyLinkList (
|
||||
List,
|
||||
HttpDestroyChildEntryInHandleBuffer,
|
||||
&Context,
|
||||
NULL
|
||||
);
|
||||
} else {
|
||||
|
||||
HttpCleanService (HttpService, UsingIpv6);
|
||||
|
||||
if (HttpService->Tcp4ChildHandle == NULL && HttpService->Tcp6ChildHandle == NULL) {
|
||||
gBS->UninstallProtocolInterface (
|
||||
NicHandle,
|
||||
&gEfiHttpServiceBindingProtocolGuid,
|
||||
ServiceBinding
|
||||
);
|
||||
FreePool (HttpService);
|
||||
}
|
||||
Status = EFI_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
return Status;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
Tests to see if this driver supports a given controller. If a child device is provided,
|
||||
it further tests to see if this driver supports creating a handle for the specified child device.
|
||||
@@ -267,41 +632,18 @@ HttpDestroyChildEntryInHandleBuffer (
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
HttpDxeDriverBindingSupported (
|
||||
HttpDxeIp4DriverBindingSupported (
|
||||
IN EFI_DRIVER_BINDING_PROTOCOL *This,
|
||||
IN EFI_HANDLE ControllerHandle,
|
||||
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
|
||||
//
|
||||
// Test for the HttpServiceBinding protocol.
|
||||
//
|
||||
Status = gBS->OpenProtocol (
|
||||
ControllerHandle,
|
||||
&gEfiHttpServiceBindingProtocolGuid,
|
||||
NULL,
|
||||
This->DriverBindingHandle,
|
||||
ControllerHandle,
|
||||
EFI_OPEN_PROTOCOL_TEST_PROTOCOL
|
||||
);
|
||||
if (!EFI_ERROR (Status)) {
|
||||
return EFI_ALREADY_STARTED;
|
||||
}
|
||||
|
||||
//
|
||||
// Test for the Tcp4 Protocol
|
||||
//
|
||||
return gBS->OpenProtocol (
|
||||
ControllerHandle,
|
||||
&gEfiTcp4ServiceBindingProtocolGuid,
|
||||
NULL,
|
||||
This->DriverBindingHandle,
|
||||
ControllerHandle,
|
||||
EFI_OPEN_PROTOCOL_TEST_PROTOCOL
|
||||
);
|
||||
|
||||
return HttpDxeSupported (
|
||||
This,
|
||||
ControllerHandle,
|
||||
RemainingDevicePath,
|
||||
IP_VERSION_4
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -342,90 +684,18 @@ HttpDxeDriverBindingSupported (
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
HttpDxeDriverBindingStart (
|
||||
HttpDxeIp4DriverBindingStart (
|
||||
IN EFI_DRIVER_BINDING_PROTOCOL *This,
|
||||
IN EFI_HANDLE ControllerHandle,
|
||||
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
HTTP_SERVICE *HttpService;
|
||||
VOID *Interface;
|
||||
|
||||
//
|
||||
// Test for the Http service binding protocol
|
||||
//
|
||||
Status = gBS->OpenProtocol (
|
||||
ControllerHandle,
|
||||
&gEfiHttpServiceBindingProtocolGuid,
|
||||
NULL,
|
||||
This->DriverBindingHandle,
|
||||
ControllerHandle,
|
||||
EFI_OPEN_PROTOCOL_TEST_PROTOCOL
|
||||
);
|
||||
|
||||
if (Status == EFI_SUCCESS) {
|
||||
return EFI_ALREADY_STARTED;
|
||||
}
|
||||
|
||||
Status = HttpCreateService (ControllerHandle, This->DriverBindingHandle, &HttpService);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
ASSERT (HttpService != NULL);
|
||||
|
||||
//
|
||||
// Create a TCP child instance, but do not configure it. This will establish the parent-child relationship.
|
||||
//
|
||||
Status = NetLibCreateServiceChild (
|
||||
ControllerHandle,
|
||||
This->DriverBindingHandle,
|
||||
&gEfiTcp4ServiceBindingProtocolGuid,
|
||||
&HttpService->TcpChildHandle
|
||||
);
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto ON_ERROR;
|
||||
}
|
||||
|
||||
Status = gBS->OpenProtocol (
|
||||
HttpService->TcpChildHandle,
|
||||
&gEfiTcp4ProtocolGuid,
|
||||
&Interface,
|
||||
This->DriverBindingHandle,
|
||||
ControllerHandle,
|
||||
EFI_OPEN_PROTOCOL_BY_DRIVER
|
||||
);
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto ON_ERROR;
|
||||
}
|
||||
|
||||
//
|
||||
// Install the HttpServiceBinding Protocol onto Controller
|
||||
//
|
||||
Status = gBS->InstallMultipleProtocolInterfaces (
|
||||
&ControllerHandle,
|
||||
&gEfiHttpServiceBindingProtocolGuid,
|
||||
&HttpService->ServiceBinding,
|
||||
NULL
|
||||
);
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto ON_ERROR;
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
|
||||
ON_ERROR:
|
||||
|
||||
if (HttpService != NULL) {
|
||||
HttpCleanService (HttpService);
|
||||
FreePool (HttpService);
|
||||
}
|
||||
|
||||
return Status;
|
||||
return HttpDxeStart (
|
||||
This,
|
||||
ControllerHandle,
|
||||
RemainingDevicePath,
|
||||
IP_VERSION_4
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -456,78 +726,176 @@ ON_ERROR:
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
HttpDxeDriverBindingStop (
|
||||
HttpDxeIp4DriverBindingStop (
|
||||
IN EFI_DRIVER_BINDING_PROTOCOL *This,
|
||||
IN EFI_HANDLE ControllerHandle,
|
||||
IN UINTN NumberOfChildren,
|
||||
IN EFI_HANDLE *ChildHandleBuffer OPTIONAL
|
||||
)
|
||||
{
|
||||
EFI_HANDLE NicHandle;
|
||||
EFI_STATUS Status;
|
||||
EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
|
||||
HTTP_SERVICE *HttpService;
|
||||
LIST_ENTRY *List;
|
||||
HTTP_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT Context;
|
||||
|
||||
//
|
||||
// HTTP driver opens TCP child, So, Controller is a TCP
|
||||
// child handle. Locate the Nic handle first. Then get the
|
||||
// HTTP private data back.
|
||||
//
|
||||
NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiTcp4ProtocolGuid);
|
||||
if (NicHandle == NULL) {
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
Status = gBS->OpenProtocol (
|
||||
NicHandle,
|
||||
&gEfiHttpServiceBindingProtocolGuid,
|
||||
(VOID **) &ServiceBinding,
|
||||
This->DriverBindingHandle,
|
||||
NicHandle,
|
||||
EFI_OPEN_PROTOCOL_GET_PROTOCOL
|
||||
);
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
HttpService = HTTP_SERVICE_FROM_PROTOCOL (ServiceBinding);
|
||||
|
||||
if (!IsListEmpty (&HttpService->ChildrenList)) {
|
||||
//
|
||||
// Destroy the HTTP child instance in ChildHandleBuffer.
|
||||
//
|
||||
List = &HttpService->ChildrenList;
|
||||
Context.ServiceBinding = ServiceBinding;
|
||||
Context.NumberOfChildren = NumberOfChildren;
|
||||
Context.ChildHandleBuffer = ChildHandleBuffer;
|
||||
Status = NetDestroyLinkList (
|
||||
List,
|
||||
HttpDestroyChildEntryInHandleBuffer,
|
||||
&Context,
|
||||
NULL
|
||||
);
|
||||
}
|
||||
|
||||
if (NumberOfChildren == 0 && IsListEmpty (&HttpService->ChildrenList)) {
|
||||
gBS->UninstallProtocolInterface (
|
||||
NicHandle,
|
||||
&gEfiHttpServiceBindingProtocolGuid,
|
||||
ServiceBinding
|
||||
return HttpDxeStop (
|
||||
This,
|
||||
ControllerHandle,
|
||||
NumberOfChildren,
|
||||
ChildHandleBuffer,
|
||||
IP_VERSION_4
|
||||
);
|
||||
|
||||
HttpCleanService (HttpService);
|
||||
|
||||
FreePool (HttpService);
|
||||
|
||||
Status = EFI_SUCCESS;
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
Tests to see if this driver supports a given controller. If a child device is provided,
|
||||
it further tests to see if this driver supports creating a handle for the specified child device.
|
||||
|
||||
This function checks to see if the driver specified by This supports the device specified by
|
||||
ControllerHandle. Drivers will typically use the device path attached to
|
||||
ControllerHandle and/or the services from the bus I/O abstraction attached to
|
||||
ControllerHandle to determine if the driver supports ControllerHandle. This function
|
||||
may be called many times during platform initialization. In order to reduce boot times, the tests
|
||||
performed by this function must be very small, and take as little time as possible to execute. This
|
||||
function must not change the state of any hardware devices, and this function must be aware that the
|
||||
device specified by ControllerHandle may already be managed by the same driver or a
|
||||
different driver. This function must match its calls to AllocatePages() with FreePages(),
|
||||
AllocatePool() with FreePool(), and OpenProtocol() with CloseProtocol().
|
||||
Because ControllerHandle may have been previously started by the same driver, if a protocol is
|
||||
already in the opened state, then it must not be closed with CloseProtocol(). This is required
|
||||
to guarantee the state of ControllerHandle is not modified by this function.
|
||||
|
||||
@param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
|
||||
@param[in] ControllerHandle The handle of the controller to test. This handle
|
||||
must support a protocol interface that supplies
|
||||
an I/O abstraction to the driver.
|
||||
@param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This
|
||||
parameter is ignored by device drivers, and is optional for bus
|
||||
drivers. For bus drivers, if this parameter is not NULL, then
|
||||
the bus driver must determine if the bus controller specified
|
||||
by ControllerHandle and the child controller specified
|
||||
by RemainingDevicePath are both supported by this
|
||||
bus driver.
|
||||
|
||||
@retval EFI_SUCCESS The device specified by ControllerHandle and
|
||||
RemainingDevicePath is supported by the driver specified by This.
|
||||
@retval EFI_ALREADY_STARTED The device specified by ControllerHandle and
|
||||
RemainingDevicePath is already being managed by the driver
|
||||
specified by This.
|
||||
@retval EFI_ACCESS_DENIED The device specified by ControllerHandle and
|
||||
RemainingDevicePath is already being managed by a different
|
||||
driver or an application that requires exclusive access.
|
||||
Currently not implemented.
|
||||
@retval EFI_UNSUPPORTED The device specified by ControllerHandle and
|
||||
RemainingDevicePath is not supported by the driver specified by This.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
HttpDxeIp6DriverBindingSupported (
|
||||
IN EFI_DRIVER_BINDING_PROTOCOL *This,
|
||||
IN EFI_HANDLE ControllerHandle,
|
||||
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
|
||||
)
|
||||
{
|
||||
return HttpDxeSupported (
|
||||
This,
|
||||
ControllerHandle,
|
||||
RemainingDevicePath,
|
||||
IP_VERSION_6
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
Starts a device controller or a bus controller.
|
||||
|
||||
The Start() function is designed to be invoked from the EFI boot service ConnectController().
|
||||
As a result, much of the error checking on the parameters to Start() has been moved into this
|
||||
common boot service. It is legal to call Start() from other locations,
|
||||
but the following calling restrictions must be followed, or the system behavior will not be deterministic.
|
||||
1. ControllerHandle must be a valid EFI_HANDLE.
|
||||
2. If RemainingDevicePath is not NULL, then it must be a pointer to a naturally aligned
|
||||
EFI_DEVICE_PATH_PROTOCOL.
|
||||
3. Prior to calling Start(), the Supported() function for the driver specified by This must
|
||||
have been called with the same calling parameters, and Supported() must have returned EFI_SUCCESS.
|
||||
|
||||
@param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
|
||||
@param[in] ControllerHandle The handle of the controller to start. This handle
|
||||
must support a protocol interface that supplies
|
||||
an I/O abstraction to the driver.
|
||||
@param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This
|
||||
parameter is ignored by device drivers, and is optional for bus
|
||||
drivers. For a bus driver, if this parameter is NULL, then handles
|
||||
for all the children of Controller are created by this driver.
|
||||
If this parameter is not NULL and the first Device Path Node is
|
||||
not the End of Device Path Node, then only the handle for the
|
||||
child device specified by the first Device Path Node of
|
||||
RemainingDevicePath is created by this driver.
|
||||
If the first Device Path Node of RemainingDevicePath is
|
||||
the End of Device Path Node, no child handle is created by this
|
||||
driver.
|
||||
|
||||
@retval EFI_SUCCESS The device was started.
|
||||
@retval EFI_ALREADY_STARTED This device is already running on ControllerHandle.
|
||||
@retval EFI_DEVICE_ERROR The device could not be started due to a device error.Currently not implemented.
|
||||
@retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
|
||||
@retval Others The driver failded to start the device.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
HttpDxeIp6DriverBindingStart (
|
||||
IN EFI_DRIVER_BINDING_PROTOCOL *This,
|
||||
IN EFI_HANDLE ControllerHandle,
|
||||
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
|
||||
)
|
||||
{
|
||||
return HttpDxeStart (
|
||||
This,
|
||||
ControllerHandle,
|
||||
RemainingDevicePath,
|
||||
IP_VERSION_6
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
Stops a device controller or a bus controller.
|
||||
|
||||
The Stop() function is designed to be invoked from the EFI boot service DisconnectController().
|
||||
As a result, much of the error checking on the parameters to Stop() has been moved
|
||||
into this common boot service. It is legal to call Stop() from other locations,
|
||||
but the following calling restrictions must be followed, or the system behavior will not be deterministic.
|
||||
1. ControllerHandle must be a valid EFI_HANDLE that was used on a previous call to this
|
||||
same driver's Start() function.
|
||||
2. The first NumberOfChildren handles of ChildHandleBuffer must all be a valid
|
||||
EFI_HANDLE. In addition, all of these handles must have been created in this driver's
|
||||
Start() function, and the Start() function must have called OpenProtocol() on
|
||||
ControllerHandle with an Attribute of EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER.
|
||||
|
||||
@param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
|
||||
@param[in] ControllerHandle A handle to the device being stopped. The handle must
|
||||
support a bus specific I/O protocol for the driver
|
||||
to use to stop the device.
|
||||
@param[in] NumberOfChildren The number of child device handles in ChildHandleBuffer.
|
||||
@param[in] ChildHandleBuffer An array of child handles to be freed. May be NULL
|
||||
if NumberOfChildren is 0.
|
||||
|
||||
@retval EFI_SUCCESS The device was stopped.
|
||||
@retval EFI_DEVICE_ERROR The device could not be stopped due to a device error.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
HttpDxeIp6DriverBindingStop (
|
||||
IN EFI_DRIVER_BINDING_PROTOCOL *This,
|
||||
IN EFI_HANDLE ControllerHandle,
|
||||
IN UINTN NumberOfChildren,
|
||||
IN EFI_HANDLE *ChildHandleBuffer OPTIONAL
|
||||
)
|
||||
{
|
||||
return HttpDxeStop (
|
||||
This,
|
||||
ControllerHandle,
|
||||
NumberOfChildren,
|
||||
ChildHandleBuffer,
|
||||
IP_VERSION_6
|
||||
);
|
||||
}
|
||||
/**
|
||||
Creates a child handle and installs a protocol.
|
||||
|
||||
@@ -557,7 +925,6 @@ HttpServiceBindingCreateChild (
|
||||
HTTP_SERVICE *HttpService;
|
||||
HTTP_PROTOCOL *HttpInstance;
|
||||
EFI_STATUS Status;
|
||||
VOID *Interface;
|
||||
EFI_TPL OldTpl;
|
||||
|
||||
if ((This == NULL) || (ChildHandle == NULL)) {
|
||||
@@ -569,6 +936,12 @@ HttpServiceBindingCreateChild (
|
||||
if (HttpInstance == NULL) {
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
HttpInstance->Signature = HTTP_PROTOCOL_SIGNATURE;
|
||||
HttpInstance->Service = HttpService;
|
||||
CopyMem (&HttpInstance->Http, &mEfiHttpTemplate, sizeof (HttpInstance->Http));
|
||||
NetMapInit (&HttpInstance->TxTokens);
|
||||
NetMapInit (&HttpInstance->RxTokens);
|
||||
|
||||
//
|
||||
// Install HTTP protocol onto ChildHandle
|
||||
@@ -584,27 +957,7 @@ HttpServiceBindingCreateChild (
|
||||
goto ON_ERROR;
|
||||
}
|
||||
|
||||
HttpInstance->Handle = *ChildHandle;
|
||||
|
||||
Status = HttpInitProtocol (HttpService, HttpInstance);
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto ON_ERROR;
|
||||
}
|
||||
|
||||
//
|
||||
// Open the default Tcp4 protocol by child.
|
||||
//
|
||||
Status = gBS->OpenProtocol (
|
||||
HttpService->TcpChildHandle,
|
||||
&gEfiTcp4ProtocolGuid,
|
||||
(VOID **) &Interface,
|
||||
gHttpDxeDriverBinding.DriverBindingHandle,
|
||||
HttpInstance->Handle,
|
||||
EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto ON_ERROR;
|
||||
}
|
||||
HttpInstance->Handle = *ChildHandle;
|
||||
|
||||
//
|
||||
// Add it to the HTTP service's child list.
|
||||
@@ -619,8 +972,9 @@ HttpServiceBindingCreateChild (
|
||||
return EFI_SUCCESS;
|
||||
|
||||
ON_ERROR:
|
||||
|
||||
HttpCleanProtocol (HttpInstance);
|
||||
|
||||
NetMapClean (&HttpInstance->TxTokens);
|
||||
NetMapClean (&HttpInstance->RxTokens);
|
||||
FreePool (HttpInstance);
|
||||
|
||||
return Status;
|
||||
@@ -664,8 +1018,8 @@ HttpServiceBindingDestroyChild (
|
||||
ChildHandle,
|
||||
&gEfiHttpProtocolGuid,
|
||||
(VOID **) &Http,
|
||||
gHttpDxeDriverBinding.DriverBindingHandle,
|
||||
ChildHandle,
|
||||
NULL,
|
||||
NULL,
|
||||
EFI_OPEN_PROTOCOL_GET_PROTOCOL
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
@@ -681,16 +1035,6 @@ HttpServiceBindingDestroyChild (
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
//
|
||||
// Close the Tcp4 protocol.
|
||||
//
|
||||
gBS->CloseProtocol (
|
||||
HttpService->TcpChildHandle,
|
||||
&gEfiTcp4ProtocolGuid,
|
||||
gHttpDxeDriverBinding.DriverBindingHandle,
|
||||
ChildHandle
|
||||
);
|
||||
|
||||
HttpInstance->InDestroy = TRUE;
|
||||
|
||||
//
|
||||
@@ -706,11 +1050,11 @@ HttpServiceBindingDestroyChild (
|
||||
HttpInstance->InDestroy = FALSE;
|
||||
return Status;
|
||||
}
|
||||
|
||||
OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
|
||||
|
||||
|
||||
HttpCleanProtocol (HttpInstance);
|
||||
|
||||
|
||||
OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
|
||||
|
||||
RemoveEntryList (&HttpInstance->Link);
|
||||
HttpService->ChildrenNumber--;
|
||||
|
||||
|
@@ -43,8 +43,12 @@
|
||||
//
|
||||
#include <Protocol/HttpUtilities.h>
|
||||
#include <Protocol/Tcp4.h>
|
||||
#include <Protocol/Tcp6.h>
|
||||
#include <Protocol/Dns4.h>
|
||||
#include <Protocol/Dns6.h>
|
||||
#include <Protocol/Ip4Config2.h>
|
||||
#include <Protocol/Ip6Config.h>
|
||||
|
||||
|
||||
//
|
||||
// Produced Protocols
|
||||
@@ -59,7 +63,9 @@
|
||||
//
|
||||
// Protocol instances
|
||||
//
|
||||
extern EFI_DRIVER_BINDING_PROTOCOL gHttpDxeDriverBinding;
|
||||
extern EFI_DRIVER_BINDING_PROTOCOL gHttpDxeIp4DriverBinding;
|
||||
extern EFI_DRIVER_BINDING_PROTOCOL gHttpDxeIp6DriverBinding;
|
||||
|
||||
extern EFI_COMPONENT_NAME2_PROTOCOL gHttpDxeComponentName2;
|
||||
extern EFI_COMPONENT_NAME_PROTOCOL gHttpDxeComponentName;
|
||||
|
||||
@@ -123,7 +129,7 @@ typedef struct {
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
HttpDxeDriverBindingSupported (
|
||||
HttpDxeIp4DriverBindingSupported (
|
||||
IN EFI_DRIVER_BINDING_PROTOCOL *This,
|
||||
IN EFI_HANDLE ControllerHandle,
|
||||
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
|
||||
@@ -166,7 +172,7 @@ HttpDxeDriverBindingSupported (
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
HttpDxeDriverBindingStart (
|
||||
HttpDxeIp4DriverBindingStart (
|
||||
IN EFI_DRIVER_BINDING_PROTOCOL *This,
|
||||
IN EFI_HANDLE ControllerHandle,
|
||||
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
|
||||
@@ -200,13 +206,142 @@ HttpDxeDriverBindingStart (
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
HttpDxeDriverBindingStop (
|
||||
HttpDxeIp4DriverBindingStop (
|
||||
IN EFI_DRIVER_BINDING_PROTOCOL *This,
|
||||
IN EFI_HANDLE ControllerHandle,
|
||||
IN UINTN NumberOfChildren,
|
||||
IN EFI_HANDLE *ChildHandleBuffer OPTIONAL
|
||||
);
|
||||
|
||||
/**
|
||||
Tests to see if this driver supports a given controller. If a child device is provided,
|
||||
it further tests to see if this driver supports creating a handle for the specified child device.
|
||||
|
||||
This function checks to see if the driver specified by This supports the device specified by
|
||||
ControllerHandle. Drivers will typically use the device path attached to
|
||||
ControllerHandle and/or the services from the bus I/O abstraction attached to
|
||||
ControllerHandle to determine if the driver supports ControllerHandle. This function
|
||||
may be called many times during platform initialization. In order to reduce boot times, the tests
|
||||
performed by this function must be very small, and take as little time as possible to execute. This
|
||||
function must not change the state of any hardware devices, and this function must be aware that the
|
||||
device specified by ControllerHandle may already be managed by the same driver or a
|
||||
different driver. This function must match its calls to AllocatePages() with FreePages(),
|
||||
AllocatePool() with FreePool(), and OpenProtocol() with CloseProtocol().
|
||||
Because ControllerHandle may have been previously started by the same driver, if a protocol is
|
||||
already in the opened state, then it must not be closed with CloseProtocol(). This is required
|
||||
to guarantee the state of ControllerHandle is not modified by this function.
|
||||
|
||||
@param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
|
||||
@param[in] ControllerHandle The handle of the controller to test. This handle
|
||||
must support a protocol interface that supplies
|
||||
an I/O abstraction to the driver.
|
||||
@param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This
|
||||
parameter is ignored by device drivers, and is optional for bus
|
||||
drivers. For bus drivers, if this parameter is not NULL, then
|
||||
the bus driver must determine if the bus controller specified
|
||||
by ControllerHandle and the child controller specified
|
||||
by RemainingDevicePath are both supported by this
|
||||
bus driver.
|
||||
|
||||
@retval EFI_SUCCESS The device specified by ControllerHandle and
|
||||
RemainingDevicePath is supported by the driver specified by This.
|
||||
@retval EFI_ALREADY_STARTED The device specified by ControllerHandle and
|
||||
RemainingDevicePath is already being managed by the driver
|
||||
specified by This.
|
||||
@retval EFI_ACCESS_DENIED The device specified by ControllerHandle and
|
||||
RemainingDevicePath is already being managed by a different
|
||||
driver or an application that requires exclusive access.
|
||||
Currently not implemented.
|
||||
@retval EFI_UNSUPPORTED The device specified by ControllerHandle and
|
||||
RemainingDevicePath is not supported by the driver specified by This.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
HttpDxeIp6DriverBindingSupported (
|
||||
IN EFI_DRIVER_BINDING_PROTOCOL *This,
|
||||
IN EFI_HANDLE ControllerHandle,
|
||||
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
|
||||
);
|
||||
|
||||
/**
|
||||
Starts a device controller or a bus controller.
|
||||
|
||||
The Start() function is designed to be invoked from the EFI boot service ConnectController().
|
||||
As a result, much of the error checking on the parameters to Start() has been moved into this
|
||||
common boot service. It is legal to call Start() from other locations,
|
||||
but the following calling restrictions must be followed, or the system behavior will not be deterministic.
|
||||
1. ControllerHandle must be a valid EFI_HANDLE.
|
||||
2. If RemainingDevicePath is not NULL, then it must be a pointer to a naturally aligned
|
||||
EFI_DEVICE_PATH_PROTOCOL.
|
||||
3. Prior to calling Start(), the Supported() function for the driver specified by This must
|
||||
have been called with the same calling parameters, and Supported() must have returned EFI_SUCCESS.
|
||||
|
||||
@param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
|
||||
@param[in] ControllerHandle The handle of the controller to start. This handle
|
||||
must support a protocol interface that supplies
|
||||
an I/O abstraction to the driver.
|
||||
@param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This
|
||||
parameter is ignored by device drivers, and is optional for bus
|
||||
drivers. For a bus driver, if this parameter is NULL, then handles
|
||||
for all the children of Controller are created by this driver.
|
||||
If this parameter is not NULL and the first Device Path Node is
|
||||
not the End of Device Path Node, then only the handle for the
|
||||
child device specified by the first Device Path Node of
|
||||
RemainingDevicePath is created by this driver.
|
||||
If the first Device Path Node of RemainingDevicePath is
|
||||
the End of Device Path Node, no child handle is created by this
|
||||
driver.
|
||||
|
||||
@retval EFI_SUCCESS The device was started.
|
||||
@retval EFI_ALREADY_STARTED This device is already running on ControllerHandle.
|
||||
@retval EFI_DEVICE_ERROR The device could not be started due to a device error.Currently not implemented.
|
||||
@retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
|
||||
@retval Others The driver failded to start the device.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
HttpDxeIp6DriverBindingStart (
|
||||
IN EFI_DRIVER_BINDING_PROTOCOL *This,
|
||||
IN EFI_HANDLE ControllerHandle,
|
||||
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
|
||||
);
|
||||
|
||||
/**
|
||||
Stops a device controller or a bus controller.
|
||||
|
||||
The Stop() function is designed to be invoked from the EFI boot service DisconnectController().
|
||||
As a result, much of the error checking on the parameters to Stop() has been moved
|
||||
into this common boot service. It is legal to call Stop() from other locations,
|
||||
but the following calling restrictions must be followed, or the system behavior will not be deterministic.
|
||||
1. ControllerHandle must be a valid EFI_HANDLE that was used on a previous call to this
|
||||
same driver's Start() function.
|
||||
2. The first NumberOfChildren handles of ChildHandleBuffer must all be a valid
|
||||
EFI_HANDLE. In addition, all of these handles must have been created in this driver's
|
||||
Start() function, and the Start() function must have called OpenProtocol() on
|
||||
ControllerHandle with an Attribute of EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER.
|
||||
|
||||
@param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
|
||||
@param[in] ControllerHandle A handle to the device being stopped. The handle must
|
||||
support a bus specific I/O protocol for the driver
|
||||
to use to stop the device.
|
||||
@param[in] NumberOfChildren The number of child device handles in ChildHandleBuffer.
|
||||
@param[in] ChildHandleBuffer An array of child handles to be freed. May be NULL
|
||||
if NumberOfChildren is 0.
|
||||
|
||||
@retval EFI_SUCCESS The device was stopped.
|
||||
@retval EFI_DEVICE_ERROR The device could not be stopped due to a device error.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
HttpDxeIp6DriverBindingStop (
|
||||
IN EFI_DRIVER_BINDING_PROTOCOL *This,
|
||||
IN EFI_HANDLE ControllerHandle,
|
||||
IN UINTN NumberOfChildren,
|
||||
IN EFI_HANDLE *ChildHandleBuffer OPTIONAL
|
||||
);
|
||||
|
||||
/**
|
||||
Creates a child handle and installs a protocol.
|
||||
|
||||
|
@@ -56,9 +56,14 @@
|
||||
gEfiHttpUtilitiesProtocolGuid ## CONSUMES
|
||||
gEfiTcp4ServiceBindingProtocolGuid ## TO_START
|
||||
gEfiTcp4ProtocolGuid ## TO_START
|
||||
gEfiTcp6ServiceBindingProtocolGuid ## TO_START
|
||||
gEfiTcp6ProtocolGuid ## TO_START
|
||||
gEfiDns4ServiceBindingProtocolGuid ## SOMETIMES_CONSUMES
|
||||
gEfiDns4ProtocolGuid ## SOMETIMES_CONSUMES
|
||||
gEfiDns6ServiceBindingProtocolGuid ## SOMETIMES_CONSUMES
|
||||
gEfiDns6ProtocolGuid ## SOMETIMES_CONSUMES
|
||||
gEfiIp4Config2ProtocolGuid ## SOMETIMES_CONSUMES
|
||||
gEfiIp6ConfigProtocolGuid ## SOMETIMES_CONSUMES
|
||||
|
||||
[UserExtensions.TianoCore."ExtraFiles"]
|
||||
HttpDxeExtra.uni
|
Binary file not shown.
@@ -51,6 +51,8 @@ EfiHttpGetModeData (
|
||||
)
|
||||
{
|
||||
HTTP_PROTOCOL *HttpInstance;
|
||||
EFI_HTTPv4_ACCESS_POINT *Http4AccessPoint;
|
||||
EFI_HTTPv6_ACCESS_POINT *Http6AccessPoint;
|
||||
|
||||
if ((This == NULL) || (HttpConfigData == NULL)) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
@@ -58,24 +60,32 @@ EfiHttpGetModeData (
|
||||
|
||||
HttpInstance = HTTP_INSTANCE_FROM_PROTOCOL (This);
|
||||
ASSERT (HttpInstance != NULL);
|
||||
|
||||
|
||||
if (HttpInstance->State < HTTP_STATE_HTTP_CONFIGED) {
|
||||
return EFI_NOT_STARTED;
|
||||
}
|
||||
|
||||
if (HttpConfigData->AccessPoint.IPv4Node == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
HttpConfigData->HttpVersion = HttpInstance->HttpVersion;
|
||||
HttpConfigData->TimeOutMillisec = HttpInstance->TimeOutMillisec;
|
||||
HttpConfigData->LocalAddressIsIPv6 = HttpInstance->LocalAddressIsIPv6;
|
||||
|
||||
CopyMem (
|
||||
HttpConfigData->AccessPoint.IPv4Node,
|
||||
&HttpInstance->IPv4Node,
|
||||
sizeof (HttpInstance->IPv4Node)
|
||||
if (HttpInstance->LocalAddressIsIPv6) {
|
||||
Http6AccessPoint = AllocateZeroPool (sizeof (EFI_HTTPv6_ACCESS_POINT));
|
||||
CopyMem (
|
||||
Http6AccessPoint,
|
||||
&HttpInstance->Ipv6Node,
|
||||
sizeof (HttpInstance->Ipv6Node)
|
||||
);
|
||||
HttpConfigData->AccessPoint.IPv6Node = Http6AccessPoint;
|
||||
} else {
|
||||
Http4AccessPoint = AllocateZeroPool (sizeof (EFI_HTTPv4_ACCESS_POINT));
|
||||
CopyMem (
|
||||
Http4AccessPoint,
|
||||
&HttpInstance->IPv4Node,
|
||||
sizeof (HttpInstance->IPv4Node)
|
||||
);
|
||||
HttpConfigData->AccessPoint.IPv4Node = Http4AccessPoint;
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
@@ -120,8 +130,13 @@ EfiHttpConfigure (
|
||||
{
|
||||
HTTP_PROTOCOL *HttpInstance;
|
||||
EFI_STATUS Status;
|
||||
|
||||
if (This == NULL) {
|
||||
|
||||
//
|
||||
// Check input parameters.
|
||||
//
|
||||
if (This == NULL ||
|
||||
(HttpConfigData != NULL && ((HttpConfigData->LocalAddressIsIPv6 && HttpConfigData->AccessPoint.IPv6Node == NULL) ||
|
||||
(!HttpConfigData->LocalAddressIsIPv6 && HttpConfigData->AccessPoint.IPv4Node == NULL)))) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
@@ -129,18 +144,7 @@ EfiHttpConfigure (
|
||||
ASSERT (HttpInstance != NULL && HttpInstance->Service != NULL);
|
||||
|
||||
if (HttpConfigData != NULL) {
|
||||
//
|
||||
// Check input parameters.
|
||||
//
|
||||
if (HttpConfigData->LocalAddressIsIPv6) {
|
||||
if (HttpConfigData->AccessPoint.IPv6Node == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
} else {
|
||||
if (HttpConfigData->AccessPoint.IPv4Node == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Now configure this HTTP instance.
|
||||
//
|
||||
@@ -151,33 +155,38 @@ EfiHttpConfigure (
|
||||
HttpInstance->HttpVersion = HttpConfigData->HttpVersion;
|
||||
HttpInstance->TimeOutMillisec = HttpConfigData->TimeOutMillisec;
|
||||
HttpInstance->LocalAddressIsIPv6 = HttpConfigData->LocalAddressIsIPv6;
|
||||
|
||||
if (HttpConfigData->LocalAddressIsIPv6) {
|
||||
return EFI_UNSUPPORTED;
|
||||
|
||||
if (HttpConfigData->LocalAddressIsIPv6) {
|
||||
CopyMem (
|
||||
&HttpInstance->Ipv6Node,
|
||||
HttpConfigData->AccessPoint.IPv6Node,
|
||||
sizeof (HttpInstance->Ipv6Node)
|
||||
);
|
||||
} else {
|
||||
CopyMem (
|
||||
&HttpInstance->IPv4Node,
|
||||
HttpConfigData->AccessPoint.IPv4Node,
|
||||
sizeof (HttpInstance->IPv4Node)
|
||||
);
|
||||
|
||||
HttpInstance->State = HTTP_STATE_HTTP_CONFIGED;
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
//
|
||||
// Creat Tcp child
|
||||
//
|
||||
Status = HttpInitProtocol (HttpInstance, HttpInstance->LocalAddressIsIPv6);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
HttpInstance->State = HTTP_STATE_HTTP_CONFIGED;
|
||||
return EFI_SUCCESS;
|
||||
|
||||
} else {
|
||||
if (HttpInstance->LocalAddressIsIPv6) {
|
||||
return EFI_UNSUPPORTED;
|
||||
} else {
|
||||
HttpCleanProtocol (HttpInstance);
|
||||
Status = HttpInitProtocol (HttpInstance->Service, HttpInstance);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
HttpInstance->State = HTTP_STATE_UNCONFIGED;
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
//
|
||||
// Reset all the resources related to HttpInsance.
|
||||
//
|
||||
HttpCleanProtocol (HttpInstance);
|
||||
HttpInstance->State = HTTP_STATE_UNCONFIGED;
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -264,10 +273,6 @@ EfiHttpRequest (
|
||||
return EFI_NOT_STARTED;
|
||||
}
|
||||
|
||||
if (HttpInstance->LocalAddressIsIPv6) {
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
//
|
||||
// Check whether the token already existed.
|
||||
//
|
||||
@@ -291,7 +296,8 @@ EfiHttpRequest (
|
||||
}
|
||||
FreePool (HttpInstance->Url);
|
||||
HttpInstance->Url = Url;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
UnicodeStrToAsciiStr (Request->Url, Url);
|
||||
UrlParser = NULL;
|
||||
@@ -340,7 +346,7 @@ EfiHttpRequest (
|
||||
Wrap->HttpToken = Token;
|
||||
Wrap->HttpInstance = HttpInstance;
|
||||
|
||||
Status = HttpCreateTcp4TxEvent (Wrap);
|
||||
Status = HttpCreateTcpTxEvent (Wrap);
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto Error1;
|
||||
}
|
||||
@@ -379,24 +385,35 @@ EfiHttpRequest (
|
||||
|
||||
if (Configure) {
|
||||
//
|
||||
// Parse Url for IPv4 address, if failed, perform DNS resolution.
|
||||
// Parse Url for IPv4 or IPv6 address, if failed, perform DNS resolution.
|
||||
//
|
||||
Status = NetLibAsciiStrToIp4 (HostName, &HttpInstance->RemoteAddr);
|
||||
if (!HttpInstance->LocalAddressIsIPv6) {
|
||||
Status = NetLibAsciiStrToIp4 (HostName, &HttpInstance->RemoteAddr);
|
||||
} else {
|
||||
Status = NetLibAsciiStrToIp6 (HostName, &HttpInstance->RemoteIpv6Addr);
|
||||
}
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
HostNameStr = AllocateZeroPool ((AsciiStrLen (HostName) + 1) * sizeof (UINT16));
|
||||
HostNameStr = AllocateZeroPool ((AsciiStrLen (HostName) + 1) * sizeof (CHAR16));
|
||||
if (HostNameStr == NULL) {
|
||||
Status = EFI_OUT_OF_RESOURCES;
|
||||
goto Error1;
|
||||
}
|
||||
|
||||
|
||||
AsciiStrToUnicodeStr (HostName, HostNameStr);
|
||||
Status = HttpDns4 (HttpInstance, HostNameStr, &HttpInstance->RemoteAddr);
|
||||
if (!HttpInstance->LocalAddressIsIPv6) {
|
||||
Status = HttpDns4 (HttpInstance, HostNameStr, &HttpInstance->RemoteAddr);
|
||||
} else {
|
||||
Status = HttpDns6 (HttpInstance, HostNameStr, &HttpInstance->RemoteIpv6Addr);
|
||||
}
|
||||
|
||||
FreePool (HostNameStr);
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto Error1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Save the RemotePort and RemoteHost.
|
||||
//
|
||||
@@ -410,7 +427,7 @@ EfiHttpRequest (
|
||||
//
|
||||
// The request URL is different from previous calls to Request(), close existing TCP instance.
|
||||
//
|
||||
ASSERT (HttpInstance->Tcp4 != NULL);
|
||||
ASSERT (HttpInstance->Tcp4 != NULL &&HttpInstance->Tcp6 != NULL);
|
||||
HttpCloseConnection (HttpInstance);
|
||||
EfiHttpCancel (This, NULL);
|
||||
}
|
||||
@@ -429,25 +446,16 @@ EfiHttpRequest (
|
||||
Wrap->TcpWrap.Method = Request->Method;
|
||||
|
||||
if (Configure) {
|
||||
//
|
||||
// Configure TCP instance.
|
||||
//
|
||||
Status = HttpConfigureTcp4 (HttpInstance, Wrap);
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto Error1;
|
||||
}
|
||||
//
|
||||
// Connect TCP.
|
||||
//
|
||||
Status = HttpConnectTcp4 (HttpInstance);
|
||||
Status = HttpInitTcp (HttpInstance, Wrap);
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto Error2;
|
||||
}
|
||||
|
||||
} else {
|
||||
//
|
||||
// For the new HTTP token, create TX TCP token events.
|
||||
//
|
||||
Status = HttpCreateTcp4TxEvent (Wrap);
|
||||
Status = HttpCreateTcpTxEvent (Wrap);
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto Error1;
|
||||
}
|
||||
@@ -488,7 +496,7 @@ EfiHttpRequest (
|
||||
//
|
||||
// Transmit the request message.
|
||||
//
|
||||
Status = HttpTransmitTcp4 (
|
||||
Status = HttpTransmitTcp (
|
||||
HttpInstance,
|
||||
Wrap,
|
||||
(UINT8*) RequestStr,
|
||||
@@ -499,11 +507,11 @@ EfiHttpRequest (
|
||||
}
|
||||
|
||||
DispatchDpc ();
|
||||
|
||||
|
||||
if (HostName != NULL) {
|
||||
FreePool (HostName);
|
||||
}
|
||||
|
||||
|
||||
return EFI_SUCCESS;
|
||||
|
||||
Error5:
|
||||
@@ -517,15 +525,19 @@ Error4:
|
||||
Error3:
|
||||
HttpCloseConnection (HttpInstance);
|
||||
|
||||
|
||||
Error2:
|
||||
HttpCloseTcp4ConnCloseEvent (HttpInstance);
|
||||
if (NULL != Wrap->TcpWrap.TxToken.CompletionToken.Event) {
|
||||
gBS->CloseEvent (Wrap->TcpWrap.TxToken.CompletionToken.Event);
|
||||
Wrap->TcpWrap.TxToken.CompletionToken.Event = NULL;
|
||||
HttpCloseTcpConnCloseEvent (HttpInstance);
|
||||
if (NULL != Wrap->TcpWrap.Tx4Token.CompletionToken.Event) {
|
||||
gBS->CloseEvent (Wrap->TcpWrap.Tx4Token.CompletionToken.Event);
|
||||
Wrap->TcpWrap.Tx4Token.CompletionToken.Event = NULL;
|
||||
}
|
||||
if (NULL != Wrap->TcpWrap.Tx6Token.CompletionToken.Event) {
|
||||
gBS->CloseEvent (Wrap->TcpWrap.Tx6Token.CompletionToken.Event);
|
||||
Wrap->TcpWrap.Tx6Token.CompletionToken.Event = NULL;
|
||||
}
|
||||
|
||||
Error1:
|
||||
|
||||
if (HostName != NULL) {
|
||||
FreePool (HostName);
|
||||
}
|
||||
@@ -541,7 +553,7 @@ Error1:
|
||||
}
|
||||
|
||||
/**
|
||||
Cancel a TxToken or RxToken.
|
||||
Cancel a user's Token.
|
||||
|
||||
@param[in] Map The HTTP instance's token queue.
|
||||
@param[in] Item Object container for one HTTP token and token's wrap.
|
||||
@@ -562,6 +574,7 @@ HttpCancelTokens (
|
||||
|
||||
EFI_HTTP_TOKEN *Token;
|
||||
HTTP_TOKEN_WRAP *Wrap;
|
||||
HTTP_PROTOCOL *HttpInstance;
|
||||
|
||||
Token = (EFI_HTTP_TOKEN *) Context;
|
||||
|
||||
@@ -575,23 +588,40 @@ HttpCancelTokens (
|
||||
|
||||
Wrap = (HTTP_TOKEN_WRAP *) Item->Value;
|
||||
ASSERT (Wrap != NULL);
|
||||
HttpInstance = Wrap->HttpInstance;
|
||||
|
||||
//
|
||||
// Free resources.
|
||||
//
|
||||
NetMapRemoveItem (Map, Item, NULL);
|
||||
|
||||
if (Wrap->TcpWrap.TxToken.CompletionToken.Event != NULL) {
|
||||
gBS->CloseEvent (Wrap->TcpWrap.TxToken.CompletionToken.Event);
|
||||
if (!HttpInstance->LocalAddressIsIPv6) {
|
||||
if (Wrap->TcpWrap.Tx4Token.CompletionToken.Event != NULL) {
|
||||
gBS->CloseEvent (Wrap->TcpWrap.Tx4Token.CompletionToken.Event);
|
||||
}
|
||||
|
||||
if (Wrap->TcpWrap.Rx4Token.CompletionToken.Event != NULL) {
|
||||
gBS->CloseEvent (Wrap->TcpWrap.Rx4Token.CompletionToken.Event);
|
||||
}
|
||||
|
||||
if (Wrap->TcpWrap.Rx4Token.Packet.RxData->FragmentTable[0].FragmentBuffer != NULL) {
|
||||
FreePool (Wrap->TcpWrap.Rx4Token.Packet.RxData->FragmentTable[0].FragmentBuffer);
|
||||
}
|
||||
|
||||
} else {
|
||||
if (Wrap->TcpWrap.Tx6Token.CompletionToken.Event != NULL) {
|
||||
gBS->CloseEvent (Wrap->TcpWrap.Tx6Token.CompletionToken.Event);
|
||||
}
|
||||
|
||||
if (Wrap->TcpWrap.Rx6Token.CompletionToken.Event != NULL) {
|
||||
gBS->CloseEvent (Wrap->TcpWrap.Rx6Token.CompletionToken.Event);
|
||||
}
|
||||
|
||||
if (Wrap->TcpWrap.Rx6Token.Packet.RxData->FragmentTable[0].FragmentBuffer != NULL) {
|
||||
FreePool (Wrap->TcpWrap.Rx6Token.Packet.RxData->FragmentTable[0].FragmentBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
if (Wrap->TcpWrap.RxToken.CompletionToken.Event != NULL) {
|
||||
gBS->CloseEvent (Wrap->TcpWrap.RxToken.CompletionToken.Event);
|
||||
}
|
||||
|
||||
if (Wrap->TcpWrap.RxToken.Packet.RxData->FragmentTable[0].FragmentBuffer != NULL) {
|
||||
FreePool (Wrap->TcpWrap.RxToken.Packet.RxData->FragmentTable[0].FragmentBuffer);
|
||||
}
|
||||
|
||||
FreePool (Wrap);
|
||||
|
||||
@@ -747,7 +777,7 @@ HttpBodyParserCallback (
|
||||
Wrap->HttpInstance->NextMsg = Data;
|
||||
|
||||
//
|
||||
// Free TxToken since already received corrsponding HTTP response.
|
||||
// Free Tx4Token or Tx6Token since already received corrsponding HTTP response.
|
||||
//
|
||||
FreePool (Wrap);
|
||||
|
||||
@@ -761,7 +791,7 @@ HttpBodyParserCallback (
|
||||
|
||||
@retval EFI_SUCCESS Allocation succeeded.
|
||||
@retval EFI_OUT_OF_RESOURCES Failed to complete the opration due to lack of resources.
|
||||
@retval EFI_NOT_READY Can't find a corresponding TxToken or
|
||||
@retval EFI_NOT_READY Can't find a corresponding Tx4Token/Tx6Token or
|
||||
the EFI_HTTP_UTILITIES_PROTOCOL is not available.
|
||||
|
||||
**/
|
||||
@@ -772,12 +802,9 @@ HttpResponseWorker (
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_HTTP_MESSAGE *HttpMsg;
|
||||
EFI_TCP4_IO_TOKEN *RxToken;
|
||||
EFI_TCP4_PROTOCOL *Tcp4;
|
||||
CHAR8 *EndofHeader;
|
||||
CHAR8 *HttpHeaders;
|
||||
UINTN SizeofHeaders;
|
||||
CHAR8 *Buffer;
|
||||
UINTN BufferSize;
|
||||
UINTN StatusCode;
|
||||
CHAR8 *Tmp;
|
||||
@@ -796,23 +823,21 @@ HttpResponseWorker (
|
||||
|
||||
HttpInstance = Wrap->HttpInstance;
|
||||
Token = Wrap->HttpToken;
|
||||
|
||||
HttpMsg = Token->Message;
|
||||
|
||||
Tcp4 = HttpInstance->Tcp4;
|
||||
ASSERT (Tcp4 != NULL);
|
||||
HttpMsg->Headers = NULL;
|
||||
HttpHeaders = NULL;
|
||||
SizeofHeaders = 0;
|
||||
Buffer = NULL;
|
||||
BufferSize = 0;
|
||||
EndofHeader = NULL;
|
||||
HttpInstance->EndofHeader = NULL;
|
||||
HttpInstance->HttpHeaders = NULL;
|
||||
HttpMsg->Headers = NULL;
|
||||
HttpHeaders = NULL;
|
||||
SizeofHeaders = 0;
|
||||
BufferSize = 0;
|
||||
EndofHeader = NULL;
|
||||
|
||||
if (HttpMsg->Data.Response != NULL) {
|
||||
//
|
||||
// Need receive the HTTP headers, prepare buffer.
|
||||
//
|
||||
Status = HttpCreateTcp4RxEventForHeader (HttpInstance);
|
||||
Status = HttpCreateTcpRxEventForHeader (HttpInstance);
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto Error;
|
||||
}
|
||||
@@ -843,71 +868,16 @@ HttpResponseWorker (
|
||||
// Check whether we cached the whole HTTP headers.
|
||||
//
|
||||
EndofHeader = AsciiStrStr (HttpHeaders, HTTP_END_OF_HDR_STR);
|
||||
}
|
||||
|
||||
RxToken = &HttpInstance->RxToken;
|
||||
RxToken->Packet.RxData->FragmentTable[0].FragmentBuffer = AllocateZeroPool (DEF_BUF_LEN);
|
||||
if (RxToken->Packet.RxData->FragmentTable[0].FragmentBuffer == NULL) {
|
||||
Status = EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
HttpInstance->EndofHeader = &EndofHeader;
|
||||
HttpInstance->HttpHeaders = &HttpHeaders;
|
||||
|
||||
Status = HttpTcpReceiveHeader (HttpInstance, &SizeofHeaders, &BufferSize);
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto Error;
|
||||
}
|
||||
|
||||
//
|
||||
// Receive the HTTP headers only when EFI_HTTP_RESPONSE_DATA is not NULL.
|
||||
//
|
||||
while (EndofHeader == NULL) {
|
||||
HttpInstance->IsRxDone = FALSE;
|
||||
RxToken->Packet.RxData->DataLength = DEF_BUF_LEN;
|
||||
RxToken->Packet.RxData->FragmentTable[0].FragmentLength = DEF_BUF_LEN;
|
||||
Status = Tcp4->Receive (Tcp4, RxToken);
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((EFI_D_ERROR, "Tcp4 receive failed: %r\n", Status));
|
||||
goto Error;
|
||||
}
|
||||
|
||||
while (!HttpInstance->IsRxDone) {
|
||||
Tcp4->Poll (Tcp4);
|
||||
}
|
||||
|
||||
Status = RxToken->CompletionToken.Status;
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto Error;
|
||||
}
|
||||
|
||||
//
|
||||
// Append the response string.
|
||||
//
|
||||
BufferSize = SizeofHeaders + RxToken->Packet.RxData->FragmentTable[0].FragmentLength;
|
||||
Buffer = AllocateZeroPool (BufferSize);
|
||||
if (Buffer == NULL) {
|
||||
Status = EFI_OUT_OF_RESOURCES;
|
||||
goto Error;
|
||||
}
|
||||
|
||||
if (HttpHeaders != NULL) {
|
||||
CopyMem (Buffer, HttpHeaders, SizeofHeaders);
|
||||
FreePool (HttpHeaders);
|
||||
}
|
||||
|
||||
CopyMem (
|
||||
Buffer + SizeofHeaders,
|
||||
RxToken->Packet.RxData->FragmentTable[0].FragmentBuffer,
|
||||
RxToken->Packet.RxData->FragmentTable[0].FragmentLength
|
||||
);
|
||||
HttpHeaders = Buffer;
|
||||
SizeofHeaders = BufferSize;
|
||||
|
||||
//
|
||||
// Check whether we received end of HTTP headers.
|
||||
//
|
||||
EndofHeader = AsciiStrStr (HttpHeaders, HTTP_END_OF_HDR_STR);
|
||||
};
|
||||
|
||||
//
|
||||
// Skip the CRLF after the HTTP headers.
|
||||
//
|
||||
EndofHeader = EndofHeader + AsciiStrLen (HTTP_END_OF_HDR_STR);
|
||||
|
||||
//
|
||||
// Cache the part of body.
|
||||
//
|
||||
@@ -927,9 +897,6 @@ HttpResponseWorker (
|
||||
HttpInstance->CacheLen = BodyLen;
|
||||
}
|
||||
|
||||
FreePool (RxToken->Packet.RxData->FragmentTable[0].FragmentBuffer);
|
||||
RxToken->Packet.RxData->FragmentTable[0].FragmentBuffer = NULL;
|
||||
|
||||
//
|
||||
// Search for Status Code.
|
||||
//
|
||||
@@ -997,7 +964,7 @@ HttpResponseWorker (
|
||||
}
|
||||
|
||||
//
|
||||
// The first TxToken not transmitted yet, insert back and return error.
|
||||
// The first Tx Token not transmitted yet, insert back and return error.
|
||||
//
|
||||
if (!ValueInItem->TcpWrap.IsTxDone) {
|
||||
goto Error2;
|
||||
@@ -1108,16 +1075,8 @@ HttpResponseWorker (
|
||||
//
|
||||
// We still need receive more data when there is no cache data and MsgParser is not NULL;
|
||||
//
|
||||
RxToken = &Wrap->TcpWrap.RxToken;
|
||||
|
||||
RxToken->Packet.RxData->DataLength = (UINT32) HttpMsg->BodyLength;
|
||||
RxToken->Packet.RxData->FragmentTable[0].FragmentLength = (UINT32) HttpMsg->BodyLength;
|
||||
RxToken->Packet.RxData->FragmentTable[0].FragmentBuffer = (VOID *) HttpMsg->Body;
|
||||
|
||||
RxToken->CompletionToken.Status = EFI_NOT_READY;
|
||||
Status = Tcp4->Receive (Tcp4, RxToken);
|
||||
Status = HttpTcpReceiveBody (Wrap, HttpMsg);
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((EFI_D_ERROR, "Tcp4 receive failed: %r\n", Status));
|
||||
goto Error;
|
||||
}
|
||||
|
||||
@@ -1130,18 +1089,7 @@ Exit:
|
||||
}
|
||||
Token->Status = Status;
|
||||
gBS->SignalEvent (Token->Event);
|
||||
|
||||
if (Wrap != NULL) {
|
||||
if (Wrap->TcpWrap.RxToken.CompletionToken.Event != NULL) {
|
||||
gBS->CloseEvent (Wrap->TcpWrap.RxToken.CompletionToken.Event);
|
||||
}
|
||||
}
|
||||
|
||||
if (HttpInstance->RxToken.CompletionToken.Event != NULL) {
|
||||
gBS->CloseEvent (HttpInstance->RxToken.CompletionToken.Event);
|
||||
HttpInstance->RxToken.CompletionToken.Event = NULL;
|
||||
}
|
||||
|
||||
HttpCloseTcpRxEvent (Wrap);
|
||||
FreePool (Wrap);
|
||||
return Status;
|
||||
|
||||
@@ -1149,28 +1097,7 @@ Error2:
|
||||
NetMapInsertHead (&HttpInstance->TxTokens, ValueInItem->HttpToken, ValueInItem);
|
||||
|
||||
Error:
|
||||
if (Wrap != NULL) {
|
||||
if (Wrap->TcpWrap.RxToken.CompletionToken.Event != NULL) {
|
||||
gBS->CloseEvent (Wrap->TcpWrap.RxToken.CompletionToken.Event);
|
||||
}
|
||||
RxToken = &Wrap->TcpWrap.RxToken;
|
||||
if (RxToken->Packet.RxData->FragmentTable[0].FragmentBuffer != NULL) {
|
||||
FreePool (RxToken->Packet.RxData->FragmentTable[0].FragmentBuffer);
|
||||
RxToken->Packet.RxData->FragmentTable[0].FragmentBuffer = NULL;
|
||||
}
|
||||
FreePool (Wrap);
|
||||
}
|
||||
|
||||
if (HttpInstance->RxToken.CompletionToken.Event != NULL) {
|
||||
gBS->CloseEvent (HttpInstance->RxToken.CompletionToken.Event);
|
||||
HttpInstance->RxToken.CompletionToken.Event = NULL;
|
||||
}
|
||||
|
||||
RxToken = &HttpInstance->RxToken;
|
||||
if (RxToken->Packet.RxData->FragmentTable[0].FragmentBuffer != NULL) {
|
||||
FreePool (RxToken->Packet.RxData->FragmentTable[0].FragmentBuffer);
|
||||
RxToken->Packet.RxData->FragmentTable[0].FragmentBuffer = NULL;
|
||||
}
|
||||
HttpTcpTokenCleanup (Wrap);
|
||||
|
||||
if (HttpHeaders != NULL) {
|
||||
FreePool (HttpHeaders);
|
||||
@@ -1268,10 +1195,6 @@ EfiHttpResponse (
|
||||
return EFI_NOT_STARTED;
|
||||
}
|
||||
|
||||
if (HttpInstance->LocalAddressIsIPv6) {
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
//
|
||||
// Check whether the token already existed.
|
||||
//
|
||||
@@ -1287,7 +1210,7 @@ EfiHttpResponse (
|
||||
Wrap->HttpInstance = HttpInstance;
|
||||
Wrap->HttpToken = Token;
|
||||
|
||||
Status = HttpCreateTcp4RxEvent (Wrap);
|
||||
Status = HttpCreateTcpRxEvent (Wrap);
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto Error;
|
||||
}
|
||||
@@ -1308,8 +1231,12 @@ EfiHttpResponse (
|
||||
|
||||
Error:
|
||||
if (Wrap != NULL) {
|
||||
if (Wrap->TcpWrap.RxToken.CompletionToken.Event != NULL) {
|
||||
gBS->CloseEvent (Wrap->TcpWrap.RxToken.CompletionToken.Event);
|
||||
if (Wrap->TcpWrap.Rx4Token.CompletionToken.Event != NULL) {
|
||||
gBS->CloseEvent (Wrap->TcpWrap.Rx4Token.CompletionToken.Event);
|
||||
}
|
||||
|
||||
if (Wrap->TcpWrap.Rx6Token.CompletionToken.Event != NULL) {
|
||||
gBS->CloseEvent (Wrap->TcpWrap.Rx6Token.CompletionToken.Event);
|
||||
}
|
||||
FreePool (Wrap);
|
||||
}
|
||||
@@ -1343,8 +1270,8 @@ EfiHttpPoll (
|
||||
IN EFI_HTTP_PROTOCOL *This
|
||||
)
|
||||
{
|
||||
HTTP_PROTOCOL *HttpInstance;
|
||||
EFI_STATUS Status;
|
||||
HTTP_PROTOCOL *HttpInstance;
|
||||
|
||||
if (This == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
@@ -1353,17 +1280,18 @@ EfiHttpPoll (
|
||||
HttpInstance = HTTP_INSTANCE_FROM_PROTOCOL (This);
|
||||
ASSERT (HttpInstance != NULL);
|
||||
|
||||
if (HttpInstance->LocalAddressIsIPv6) {
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
if (HttpInstance->Tcp4 == NULL || HttpInstance->State != HTTP_STATE_TCP_CONNECTED) {
|
||||
if (HttpInstance->State != HTTP_STATE_TCP_CONNECTED || (HttpInstance->Tcp4 == NULL &&
|
||||
HttpInstance->Tcp6 == NULL)) {
|
||||
return EFI_NOT_STARTED;
|
||||
}
|
||||
|
||||
Status = HttpInstance->Tcp4->Poll (HttpInstance->Tcp4);
|
||||
|
||||
|
||||
if (HttpInstance->LocalAddressIsIPv6) {
|
||||
Status = HttpInstance->Tcp6->Poll (HttpInstance->Tcp6);
|
||||
} else {
|
||||
Status = HttpInstance->Tcp4->Poll (HttpInstance->Tcp4);
|
||||
}
|
||||
|
||||
DispatchDpc ();
|
||||
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -27,6 +27,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
HTTP_SERVICE_SIGNATURE \
|
||||
)
|
||||
|
||||
|
||||
//
|
||||
// The state of HTTP protocol. It starts from UNCONFIGED.
|
||||
//
|
||||
@@ -58,18 +59,23 @@ typedef struct _HTTP_SERVICE {
|
||||
EFI_SERVICE_BINDING_PROTOCOL ServiceBinding;
|
||||
EFI_HANDLE ImageHandle;
|
||||
EFI_HANDLE ControllerHandle;
|
||||
EFI_HANDLE Tcp4ChildHandle;
|
||||
EFI_HANDLE Tcp6ChildHandle;
|
||||
LIST_ENTRY ChildrenList;
|
||||
UINTN ChildrenNumber;
|
||||
EFI_HANDLE TcpChildHandle;
|
||||
INTN State;
|
||||
} HTTP_SERVICE;
|
||||
|
||||
typedef struct {
|
||||
EFI_TCP4_IO_TOKEN TxToken;
|
||||
EFI_TCP4_TRANSMIT_DATA TxData;
|
||||
EFI_TCP4_IO_TOKEN Tx4Token;
|
||||
EFI_TCP4_TRANSMIT_DATA Tx4Data;
|
||||
EFI_TCP6_IO_TOKEN Tx6Token;
|
||||
EFI_TCP6_TRANSMIT_DATA Tx6Data;
|
||||
EFI_TCP4_IO_TOKEN Rx4Token;
|
||||
EFI_TCP4_RECEIVE_DATA Rx4Data;
|
||||
EFI_TCP6_IO_TOKEN Rx6Token;
|
||||
EFI_TCP6_RECEIVE_DATA Rx6Data;
|
||||
BOOLEAN IsTxDone;
|
||||
EFI_TCP4_IO_TOKEN RxToken;
|
||||
EFI_TCP4_RECEIVE_DATA RxData;
|
||||
BOOLEAN IsRxDone;
|
||||
UINTN BodyLen;
|
||||
EFI_HTTP_METHOD Method;
|
||||
@@ -84,26 +90,43 @@ typedef struct _HTTP_PROTOCOL {
|
||||
BOOLEAN InDestroy;
|
||||
INTN State;
|
||||
|
||||
EFI_HANDLE TcpChildHandle;
|
||||
EFI_HANDLE Tcp4ChildHandle;
|
||||
EFI_TCP4_PROTOCOL *Tcp4;
|
||||
EFI_TCP4_CONFIG_DATA Tcp4CfgData;
|
||||
EFI_TCP4_OPTION Tcp4Option;
|
||||
|
||||
EFI_TCP4_CONNECTION_TOKEN ConnToken;
|
||||
BOOLEAN IsConnDone;
|
||||
EFI_TCP4_CLOSE_TOKEN CloseToken;
|
||||
BOOLEAN IsCloseDone;
|
||||
|
||||
EFI_TCP4_CONNECTION_TOKEN Tcp4ConnToken;
|
||||
BOOLEAN IsTcp4ConnDone;
|
||||
EFI_TCP4_CLOSE_TOKEN Tcp4CloseToken;
|
||||
BOOLEAN IsTcp4CloseDone;
|
||||
CHAR8 *RemoteHost;
|
||||
UINT16 RemotePort;
|
||||
EFI_IPv4_ADDRESS RemoteAddr;
|
||||
|
||||
EFI_HANDLE Tcp6ChildHandle;
|
||||
EFI_TCP6_PROTOCOL *Tcp6;
|
||||
EFI_TCP6_CONFIG_DATA Tcp6CfgData;
|
||||
EFI_TCP6_OPTION Tcp6Option;
|
||||
|
||||
EFI_TCP6_CONNECTION_TOKEN Tcp6ConnToken;
|
||||
BOOLEAN IsTcp6ConnDone;
|
||||
EFI_TCP6_CLOSE_TOKEN Tcp6CloseToken;
|
||||
BOOLEAN IsTcp6CloseDone;
|
||||
EFI_IPv6_ADDRESS RemoteIpv6Addr;
|
||||
|
||||
|
||||
|
||||
//
|
||||
// RxToken used for receiving HTTP header.
|
||||
// Rx4Token or Rx6Token used for receiving HTTP header.
|
||||
//
|
||||
EFI_TCP4_IO_TOKEN RxToken;
|
||||
EFI_TCP4_RECEIVE_DATA RxData;
|
||||
EFI_TCP4_IO_TOKEN Rx4Token;
|
||||
EFI_TCP4_RECEIVE_DATA Rx4Data;
|
||||
EFI_TCP6_IO_TOKEN Rx6Token;
|
||||
EFI_TCP6_RECEIVE_DATA Rx6Data;
|
||||
BOOLEAN IsRxDone;
|
||||
|
||||
CHAR8 **EndofHeader;
|
||||
CHAR8 **HttpHeaders;
|
||||
CHAR8 *CacheBody;
|
||||
CHAR8 *NextMsg;
|
||||
UINTN CacheLen;
|
||||
@@ -119,6 +142,7 @@ typedef struct _HTTP_PROTOCOL {
|
||||
BOOLEAN LocalAddressIsIPv6;
|
||||
|
||||
EFI_HTTPv4_ACCESS_POINT IPv4Node;
|
||||
EFI_HTTPv6_ACCESS_POINT Ipv6Node;
|
||||
|
||||
NET_MAP TxTokens;
|
||||
NET_MAP RxTokens;
|
||||
@@ -158,7 +182,7 @@ HttpCommonNotify (
|
||||
);
|
||||
|
||||
/**
|
||||
Create events for the TCP4 connection token and TCP4 close token.
|
||||
Create events for the TCP connection token and TCP close token.
|
||||
|
||||
@param[in] HttpInstance Pointer to HTTP_PROTOCOL structure.
|
||||
|
||||
@@ -167,23 +191,23 @@ HttpCommonNotify (
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
HttpCreateTcp4ConnCloseEvent (
|
||||
HttpCreateTcpConnCloseEvent (
|
||||
IN HTTP_PROTOCOL *HttpInstance
|
||||
);
|
||||
|
||||
/**
|
||||
Close events in the TCP4 connection token and TCP4 close token.
|
||||
Close events in the TCP connection token and TCP close token.
|
||||
|
||||
@param[in] HttpInstance Pointer to HTTP_PROTOCOL structure.
|
||||
|
||||
**/
|
||||
VOID
|
||||
HttpCloseTcp4ConnCloseEvent (
|
||||
HttpCloseTcpConnCloseEvent (
|
||||
IN HTTP_PROTOCOL *HttpInstance
|
||||
);
|
||||
|
||||
/**
|
||||
Create event for the TCP4 transmit token.
|
||||
Create event for the TCP transmit token.
|
||||
|
||||
@param[in] Wrap Point to HTTP token's wrap data.
|
||||
|
||||
@@ -192,12 +216,12 @@ HttpCloseTcp4ConnCloseEvent (
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
HttpCreateTcp4TxEvent (
|
||||
HttpCreateTcpTxEvent (
|
||||
IN HTTP_TOKEN_WRAP *Wrap
|
||||
);
|
||||
|
||||
/**
|
||||
Create event for the TCP4 receive token which is used to receive HTTP header.
|
||||
Create event for the TCP receive token which is used to receive HTTP header.
|
||||
|
||||
@param[in] HttpInstance Pointer to HTTP_PROTOCOL structure.
|
||||
|
||||
@@ -206,12 +230,12 @@ HttpCreateTcp4TxEvent (
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
HttpCreateTcp4RxEventForHeader (
|
||||
HttpCreateTcpRxEventForHeader (
|
||||
IN HTTP_PROTOCOL *HttpInstance
|
||||
);
|
||||
|
||||
/**
|
||||
Create event for the TCP4 receive token which is used to receive HTTP body.
|
||||
Create event for the TCP receive token which is used to receive HTTP body.
|
||||
|
||||
@param[in] Wrap Point to HTTP token's wrap data.
|
||||
|
||||
@@ -220,15 +244,26 @@ HttpCreateTcp4RxEventForHeader (
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
HttpCreateTcp4RxEvent (
|
||||
HttpCreateTcpRxEvent (
|
||||
IN HTTP_TOKEN_WRAP *Wrap
|
||||
);
|
||||
|
||||
/**
|
||||
Close Events for Tcp Receive Tokens for HTTP body and HTTP header.
|
||||
|
||||
@param[in] Wrap Pointer to HTTP token's wrap data.
|
||||
|
||||
**/
|
||||
VOID
|
||||
HttpCloseTcpRxEvent (
|
||||
IN HTTP_TOKEN_WRAP *Wrap
|
||||
);
|
||||
|
||||
/**
|
||||
Intiialize the HTTP_PROTOCOL structure to the unconfigured state.
|
||||
|
||||
@param[in] HttpSb The HTTP service private instance.
|
||||
@param[in, out] HttpInstance Pointer to HTTP_PROTOCOL structure.
|
||||
@param[in] IpVersion Indicate us TCP4 protocol or TCP6 protocol.
|
||||
|
||||
@retval EFI_SUCCESS HTTP_PROTOCOL structure is initialized successfully.
|
||||
@retval Others Other error as indicated.
|
||||
@@ -236,8 +271,8 @@ HttpCreateTcp4RxEvent (
|
||||
**/
|
||||
EFI_STATUS
|
||||
HttpInitProtocol (
|
||||
IN HTTP_SERVICE *HttpSb,
|
||||
IN OUT HTTP_PROTOCOL *HttpInstance
|
||||
IN OUT HTTP_PROTOCOL *HttpInstance,
|
||||
IN BOOLEAN IpVersion
|
||||
);
|
||||
|
||||
/**
|
||||
@@ -295,6 +330,22 @@ HttpConfigureTcp4 (
|
||||
IN HTTP_TOKEN_WRAP *Wrap
|
||||
);
|
||||
|
||||
/**
|
||||
Configure TCP6 protocol child.
|
||||
|
||||
@param[in] HttpInstance The HTTP instance private data.
|
||||
@param[in] Wrap The HTTP token's wrap data.
|
||||
|
||||
@retval EFI_SUCCESS The TCP6 protocol child is configured.
|
||||
@retval Others Other error as indicated.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
HttpConfigureTcp6 (
|
||||
IN HTTP_PROTOCOL *HttpInstance,
|
||||
IN HTTP_TOKEN_WRAP *Wrap
|
||||
);
|
||||
|
||||
/**
|
||||
Check existing TCP connection, if in error state, receover TCP4 connection.
|
||||
|
||||
@@ -311,7 +362,22 @@ HttpConnectTcp4 (
|
||||
);
|
||||
|
||||
/**
|
||||
Send the HTTP message through TCP4.
|
||||
Check existing TCP connection, if in error state, recover TCP6 connection.
|
||||
|
||||
@param[in] HttpInstance The HTTP instance private data.
|
||||
|
||||
@retval EFI_SUCCESS The TCP connection is established.
|
||||
@retval EFI_NOT_READY TCP6 protocol child is not created or configured.
|
||||
@retval Others Other error as indicated.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
HttpConnectTcp6 (
|
||||
IN HTTP_PROTOCOL *HttpInstance
|
||||
);
|
||||
|
||||
/**
|
||||
Send the HTTP message through TCP4 or TCP6.
|
||||
|
||||
@param[in] HttpInstance The HTTP instance private data.
|
||||
@param[in] Wrap The HTTP token's wrap data.
|
||||
@@ -323,7 +389,7 @@ HttpConnectTcp4 (
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
HttpTransmitTcp4 (
|
||||
HttpTransmitTcp (
|
||||
IN HTTP_PROTOCOL *HttpInstance,
|
||||
IN HTTP_TOKEN_WRAP *Wrap,
|
||||
IN UINT8 *TxString,
|
||||
@@ -346,7 +412,7 @@ HttpMappingToStatusCode (
|
||||
|
||||
/**
|
||||
Check whether the user's token or event has already
|
||||
been enqueue on HTTP TxToken or RxToken list.
|
||||
been enqueue on HTTP Tx or Rx Token list.
|
||||
|
||||
@param[in] Map The container of either user's transmit or receive
|
||||
token.
|
||||
@@ -367,7 +433,7 @@ HttpTokenExist (
|
||||
);
|
||||
|
||||
/**
|
||||
Check whether the HTTP message associated with TxToken is already sent out.
|
||||
Check whether the HTTP message associated with TxToken or Tx6Token is already sent out.
|
||||
|
||||
@param[in] Map The container of TxToken.
|
||||
@param[in] Item Current item to check against.
|
||||
@@ -385,10 +451,26 @@ HttpTcpNotReady (
|
||||
IN VOID *Context
|
||||
);
|
||||
|
||||
/**
|
||||
Initialize TCP related data.
|
||||
|
||||
@param[in] HttpInstance The HTTP instance private data.
|
||||
@param[in] Wrap The HTTP token's wrap data.
|
||||
|
||||
@retval EFI_SUCCESS The initialization of TCP instance is done.
|
||||
@retval Others Other error as indicated.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
HttpInitTcp (
|
||||
IN HTTP_PROTOCOL *HttpInstance,
|
||||
IN HTTP_TOKEN_WRAP *Wrap
|
||||
);
|
||||
|
||||
/**
|
||||
Transmit the HTTP mssage by processing the associated HTTP token.
|
||||
|
||||
@param[in] Map The container of TxToken.
|
||||
@param[in] Map The container of TxToken or Tx6Token.
|
||||
@param[in] Item Current item to check against.
|
||||
@param[in] Context The Token to check againist.
|
||||
|
||||
@@ -408,7 +490,7 @@ HttpTcpTransmit (
|
||||
/**
|
||||
Receive the HTTP response by processing the associated HTTP token.
|
||||
|
||||
@param[in] Map The container of RxToken.
|
||||
@param[in] Map The container of Rx4Token or Rx6Token.
|
||||
@param[in] Item Current item to check against.
|
||||
@param[in] Context The Token to check againist.
|
||||
|
||||
@@ -425,6 +507,51 @@ HttpTcpReceive (
|
||||
IN VOID *Context
|
||||
);
|
||||
|
||||
/**
|
||||
Receive the HTTP header by processing the associated HTTP token.
|
||||
|
||||
@param[in] HttpInstance The HTTP instance private data.
|
||||
@param[in, out] SizeofHeaders The HTTP header length.
|
||||
@param[in, out] BufferSize The size of buffer to cacahe the header message.
|
||||
|
||||
@retval EFI_SUCCESS The HTTP header is received.
|
||||
@retval Others Other errors as indicated.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
HttpTcpReceiveHeader (
|
||||
IN HTTP_PROTOCOL *HttpInstance,
|
||||
IN OUT UINTN *SizeofHeaders,
|
||||
IN OUT UINTN *BufferSize
|
||||
);
|
||||
|
||||
/**
|
||||
Receive the HTTP body by processing the associated HTTP token.
|
||||
|
||||
@param[in] Wrap The HTTP token's wrap data.
|
||||
@param[in] HttpMsg The HTTP message data.
|
||||
|
||||
@retval EFI_SUCCESS The HTTP body is received.
|
||||
@retval Others Other error as indicated.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
HttpTcpReceiveBody (
|
||||
IN HTTP_TOKEN_WRAP *Wrap,
|
||||
IN EFI_HTTP_MESSAGE *HttpMsg
|
||||
);
|
||||
|
||||
/**
|
||||
Clean up Tcp Tokens while the Tcp transmission error occurs.
|
||||
|
||||
@param[in] Wrap Pointer to HTTP token's wrap data.
|
||||
|
||||
**/
|
||||
VOID
|
||||
HttpTcpTokenCleanup (
|
||||
IN HTTP_TOKEN_WRAP *Wrap
|
||||
);
|
||||
|
||||
/**
|
||||
Generate HTTP request string.
|
||||
|
||||
|
Reference in New Issue
Block a user