Update the sockets library code

* Passes conformance and functional tests.
* Builds with GCC 4.4 compiler.

Signed-off by: lpleahy


git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@12497 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
lpleahy
2011-09-30 23:02:35 +00:00
parent df7499fcc1
commit a88c31639b
40 changed files with 8998 additions and 6826 deletions

View File

@@ -0,0 +1,322 @@
/** @file
SocketDxe support routines
Copyright (c) 2011, Intel Corporation
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include "Socket.h"
/**
Creates a child handle and installs gEfiSocketProtocolGuid.
This routine creates a child handle for the socket driver and
installs the ::gEfiSocketProtocolGuid on that handle with a pointer
to the ::EFI_SOCKET_PROTOCOL structure address.
This routine is called by ::EslServiceGetProtocol in UseSocketDxe
when the socket application is linked with UseSocketDxe.
@param [in] pThis Address of the EFI_SERVICE_BINDING_PROTOCOL structure.
@param [in] pChildHandle Pointer to the handle of the child to create. If it is NULL,
then a new handle is created. If it is a pointer to an existing UEFI handle,
then the protocol is added to the existing UEFI handle.
@retval EFI_SUCCESS The protocol was added to ChildHandle.
@retval EFI_INVALID_PARAMETER ChildHandle is NULL.
@retval EFI_OUT_OF_RESOURCES There are not enough resources availabe to create
the child
@retval other The child handle was not created
**/
EFI_STATUS
EFIAPI
EslDxeCreateChild (
IN EFI_SERVICE_BINDING_PROTOCOL * pThis,
IN OUT EFI_HANDLE * pChildHandle
)
{
ESL_SOCKET * pSocket;
EFI_STATUS Status;
DBG_ENTER ( );
//
// Create a socket structure
//
Status = EslSocketAllocate ( pChildHandle,
DEBUG_SOCKET,
&pSocket );
//
// Return the operation status
//
DBG_EXIT_STATUS ( Status );
return Status;
}
/**
Removes gEfiSocketProtocolGuid and destroys the child handle.
This routine uninstalls ::gEfiSocketProtocolGuid from the child handle
and destroys the child handle if necessary.
This routine is called from ???.
@param [in] pThis Address of the EFI_SERVICE_BINDING_PROTOCOL structure.
@param [in] ChildHandle Handle of the child to destroy
@retval EFI_SUCCESS The protocol was removed from ChildHandle.
@retval EFI_UNSUPPORTED ChildHandle does not support the protocol that is being removed.
@retval EFI_INVALID_PARAMETER Child handle is not a valid UEFI Handle.
@retval EFI_ACCESS_DENIED The protocol could not be removed from the ChildHandle
because its services are being used.
@retval other The child handle was not destroyed
**/
EFI_STATUS
EFIAPI
EslDxeDestroyChild (
IN EFI_SERVICE_BINDING_PROTOCOL * pThis,
IN EFI_HANDLE ChildHandle
)
{
ESL_LAYER * pLayer;
ESL_SOCKET * pSocket;
ESL_SOCKET * pSocketPrevious;
EFI_SOCKET_PROTOCOL * pSocketProtocol;
EFI_STATUS Status;
EFI_TPL TplPrevious;
DBG_ENTER ( );
//
// Locate the socket control structure
//
pLayer = &mEslLayer;
Status = gBS->OpenProtocol (
ChildHandle,
&gEfiSocketProtocolGuid,
(VOID **)&pSocketProtocol,
pLayer->ImageHandle,
NULL,
EFI_OPEN_PROTOCOL_GET_PROTOCOL
);
if ( !EFI_ERROR ( Status )) {
pSocket = SOCKET_FROM_PROTOCOL ( pSocketProtocol );
//
// Synchronize with the socket layer
//
RAISE_TPL ( TplPrevious, TPL_SOCKETS );
//
// Walk the socket list
//
pSocketPrevious = pLayer->pSocketList;
if ( NULL != pSocketPrevious ) {
if ( pSocket == pSocketPrevious ) {
//
// Remove the socket from the head of the list
//
pLayer->pSocketList = pSocket->pNext;
}
else {
//
// Find the socket in the middle of the list
//
while (( NULL != pSocketPrevious )
&& ( pSocket != pSocketPrevious->pNext )) {
//
// Set the next socket
//
pSocketPrevious = pSocketPrevious->pNext;
}
if ( NULL != pSocketPrevious ) {
//
// Remove the socket from the middle of the list
//
pSocketPrevious = pSocket->pNext;
}
}
}
else {
DEBUG (( DEBUG_ERROR | DEBUG_POOL,
"ERROR - Socket list is empty!\r\n" ));
}
//
// Release the socket layer synchronization
//
RESTORE_TPL ( TplPrevious );
//
// Determine if the socket was found
//
if ( NULL != pSocketPrevious ) {
pSocket->pNext = NULL;
//
// Remove the socket protocol
//
Status = gBS->UninstallMultipleProtocolInterfaces (
ChildHandle,
&gEfiSocketProtocolGuid,
&pSocket->SocketProtocol,
NULL );
if ( !EFI_ERROR ( Status )) {
DEBUG (( DEBUG_POOL | DEBUG_INFO,
"Removed: gEfiSocketProtocolGuid from 0x%08x\r\n",
ChildHandle ));
//
// Free the socket structure
//
Status = gBS->FreePool ( pSocket );
if ( !EFI_ERROR ( Status )) {
DEBUG (( DEBUG_POOL,
"0x%08x: Free pSocket, %d bytes\r\n",
pSocket,
sizeof ( *pSocket )));
}
else {
DEBUG (( DEBUG_ERROR | DEBUG_POOL,
"ERROR - Failed to free pSocket 0x%08x, Status: %r\r\n",
pSocket,
Status ));
}
}
else {
DEBUG (( DEBUG_ERROR | DEBUG_POOL | DEBUG_INFO,
"ERROR - Failed to remove gEfiSocketProtocolGuid from 0x%08x, Status: %r\r\n",
ChildHandle,
Status ));
}
}
else {
DEBUG (( DEBUG_ERROR | DEBUG_INFO,
"ERROR - The socket was not in the socket list!\r\n" ));
Status = EFI_NOT_FOUND;
}
}
else {
DEBUG (( DEBUG_ERROR,
"ERROR - Failed to open socket protocol on 0x%08x, Status; %r\r\n",
ChildHandle,
Status ));
}
//
// Return the operation status
//
DBG_EXIT_STATUS ( Status );
return Status;
}
/**
Install the socket service
This routine installs the ::gEfiSocketServiceBindingProtocolGuid
on the SocketDxe image handle to announce the availability
of the socket layer to the rest of EFI.
SocketDxe's EntryPoint routine calls this routine to
make the socket layer available.
@param [in] pImageHandle Address of the image handle
@retval EFI_SUCCESS Service installed successfully
**/
EFI_STATUS
EFIAPI
EslDxeInstall (
IN EFI_HANDLE * pImageHandle
)
{
EFI_STATUS Status;
//
// Install the socket service binding protocol
//
Status = gBS->InstallMultipleProtocolInterfaces (
pImageHandle,
&gEfiSocketServiceBindingProtocolGuid,
mEslLayer.pServiceBinding,
NULL
);
if ( !EFI_ERROR ( Status )) {
DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,
"Installed: gEfiSocketServiceBindingProtocolGuid on 0x%08x\r\n",
*pImageHandle ));
}
else {
DEBUG (( DEBUG_ERROR | DEBUG_POOL | DEBUG_INIT,
"ERROR - InstallMultipleProtocolInterfaces failed, Status: %r\r\n",
Status ));
}
//
// Return the operation status
//
return Status;
}
/**
Uninstall the socket service
This routine removes the gEfiSocketServiceBindingProtocolGuid from
the SocketDxe image handle to notify EFI that the socket layer
is no longer available.
SocketDxe's DriverUnload routine calls this routine to remove the
socket layer.
@param [in] ImageHandle Handle for the image.
@retval EFI_SUCCESS Service installed successfully
**/
EFI_STATUS
EFIAPI
EslDxeUninstall (
IN EFI_HANDLE ImageHandle
)
{
EFI_STATUS Status;
//
// Install the socket service binding protocol
//
Status = gBS->UninstallMultipleProtocolInterfaces (
ImageHandle,
&gEfiSocketServiceBindingProtocolGuid,
mEslLayer.pServiceBinding,
NULL
);
if ( !EFI_ERROR ( Status )) {
DEBUG (( DEBUG_POOL | DEBUG_INIT,
"Removed: gEfiSocketServiceBindingProtocolGuid from 0x%08x\r\n",
ImageHandle ));
}
else {
DEBUG (( DEBUG_ERROR | DEBUG_POOL | DEBUG_INIT,
"ERROR - Failed to remove gEfiSocketServiceBindingProtocolGuid from 0x%08x, Status: %r\r\n",
ImageHandle,
Status ));
}
//
// Return the operation status
//
return Status;
}

View File

@@ -28,7 +28,9 @@
#
[Sources.common]
DxeSupport.c
Init.c
Ip4.c
Service.c
Socket.c
Tcp4.c
@@ -43,10 +45,13 @@
[LibraryClasses]
BaseMemoryLib
DebugLib
MemoryAllocationLib
UefiBootServicesTableLib
UefiLib
[Protocols]
gEfiIp4ProtocolGuid
gEfiIp4ServiceBindingProtocolGuid
gEfiTcp4ProtocolGuid
gEfiTcp4ServiceBindingProtocolGuid
gEfiUdp4ProtocolGuid

View File

@@ -18,7 +18,22 @@
/**
EFI Socket Library Constructor
@retval EFI_SUCCESS The initialization was successful
This routine supports an implementation dependent constructor
depending upon whether the library is linked to a socket
application or the SocketDxe driver. The following modules
declare the redirection for the constructor in ::mpfnEslConstructor:
<ul>
<li>StdLib/EfiSocketLib/UseSocketLib.c - Application links against EfiSocketLib</li>
<li>StdLib/SocketDxe/EntryUnload.c - SocketDxe links against EfiSocketLib</li>
</ul>
The EfiSocketLib.inf file lists ::EslConstructor as the CONSTRUCTOR
in the [Defines] section. As a result, this routine is called by
the ProcessLibraryConstructorList routine of the AutoGen.c module
in the Build directory associated with the socket application or
the SocketDxe driver.
@retval EFI_SUCCESS The socket layer initialization was successful
**/
EFI_STATUS
@@ -54,7 +69,22 @@ EslConstructor (
/**
EFI Socket Library Destructor
@retval EFI_SUCCESS The shutdown was successful
This routine supports an implementation dependent destructor
depending upon whether the library is linked to a socket
application or the SocketDxe driver. The following modules
declare the redirection for the destructor in ::mpfnEslDestructor:
<ul>
<li>StdLib/EfiSocketLib/UseSocketLib.c - Application links against EfiSocketLib</li>
<li>StdLib/SocketDxe/EntryUnload.c - SocketDxe links against EfiSocketLib</li>
</ul>
The EfiSocketLib.inf file lists ::EslDestructor as the DESTRUCTOR
in the [Defines] section. As a result, this routine is called by
the ProcessLibraryDestructorList routine of the AutoGen.c module
in the Build directory associated with the socket application or
the SocketDxe driver.
@retval EFI_SUCCESS The socket layer shutdown was successful
**/
EFI_STATUS

1264
StdLib/EfiSocketLib/Ip4.c Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,31 @@
The following issues exist with the EFI Socket Library:
* Don't run socket applications or the socket driver for a long time - The IPv4Config
and DHCP protocols are not properly running the renew and lease expiration timers.
When the DHCP lease expires it is possible for a duplicate IP address to exist on
the network. HSD 206136
* Network adapters must be initialized prior to running the socket application - Static
and dynamic IP address need to be properly assigned to the network adapters on the
system. Note that sockets does not assign the IP addresses since it does not
understand how the system is connected to the network!
* The default device must contain the Efi\etc directory populated with files containing
the proper network configuration - A template set of files is in StdLib\Efi\etc. Note
that the resolv.conf file contains the set of DNS servers.
* Since DHCP is not running when the sockets application is running, the last negotiated
packet is no longer available. As a result, any of the options that DHCP did negotiate
are no longer available for sockets such as the list of DNS servers.
* DHCP does not request the domain name and domain name server (DNS) addresses. This
requires that sockets use configuration files in Efi\etc!
* TCPv4 transfer rate is slow (< 10 Mbits/sec) - This is an unidentified issue.
* Raw socket applications are not able to pass the IP header as part of their
payload by using the IP option IP_HDRINCL. This is because the UEFI IPv4 driver
(Ip4Dxe) does not support RawData. HSD 206136
* Only version 4 of the UEFI network stack is supported

View File

@@ -14,15 +14,16 @@
#include "Socket.h"
EFI_TCP4_PROTOCOL * mpEfiTcpClose4 [ 1024 ];
/**
Connect to the network service bindings
Walk the network service protocols on the controller handle and
locate any that are not in use. Create service structures to
manage the service binding for the socket driver.
locate any that are not in use. Create ::ESL_SERVICE structures to
manage the network layer interfaces for the socket driver. Tag
each of the network interfaces that are being used. Finally, this
routine calls ESL_SOCKET_BINDING::pfnInitialize to prepare the network
interface for use by the socket layer.
@param [in] BindingHandle Handle for protocol binding.
@param [in] Controller Handle of device to work with.
@@ -40,11 +41,13 @@ EslServiceConnect (
{
BOOLEAN bInUse;
UINTN LengthInBytes;
CONST DT_SOCKET_BINDING * pEnd;
UINT8 * pBuffer;
CONST ESL_SOCKET_BINDING * pEnd;
VOID * pJunk;
VOID * pInterface;
DT_SERVICE * pService;
CONST DT_SOCKET_BINDING * pSocketBinding;
ESL_SERVICE ** ppServiceListHead;
ESL_SERVICE * pService;
CONST ESL_SOCKET_BINDING * pSocketBinding;
EFI_SERVICE_BINDING_PROTOCOL * pServiceBinding;
EFI_STATUS Status;
EFI_TPL TplPrevious;
@@ -68,7 +71,7 @@ EslServiceConnect (
Status = gBS->OpenProtocol (
Controller,
pSocketBinding->pNetworkBinding,
&pInterface,
(VOID**)&pServiceBinding,
BindingHandle,
Controller,
EFI_OPEN_PROTOCOL_GET_PROTOCOL
@@ -108,7 +111,7 @@ EslServiceConnect (
pService->Signature = SERVICE_SIGNATURE;
pService->pSocketBinding = pSocketBinding;
pService->Controller = Controller;
pService->pInterface = pInterface;
pService->pServiceBinding = pServiceBinding;
//
// Mark the controller in use
@@ -154,9 +157,13 @@ EslServiceConnect (
RAISE_TPL ( TplPrevious, TPL_SOCKETS );
//
// Initialize the service
// Connect the service to the list
//
Status = pSocketBinding->pfnInitialize ( pService );
pBuffer = (UINT8 *)&mEslLayer;
pBuffer = &pBuffer[ pSocketBinding->ServiceListOffset ];
ppServiceListHead = (ESL_SERVICE **)pBuffer;
pService->pNext = *ppServiceListHead;
*ppServiceListHead = pService;
//
// Release the socket layer synchronization
@@ -253,12 +260,13 @@ EslServiceConnect (
/**
Shutdown the network connections to this controller by removing
NetworkInterfaceIdentifier protocol and closing the DevicePath
and PciIo protocols on Controller.
Shutdown the connections to the network layer by locating the
tags on the network interfaces established by ::EslServiceConnect.
This routine shutdowns any activity on the network interface and
then frees the ::ESL_SERVICE structures.
@param [in] BindingHandle Handle for protocol binding.
@param [in] Controller Handle of device to stop driver on.
@param [in] Controller Handle of device to stop driver on.
@retval EFI_SUCCESS This driver is removed Controller.
@retval EFI_DEVICE_ERROR The device could not be stopped due to a device error.
@@ -272,9 +280,13 @@ EslServiceDisconnect (
IN EFI_HANDLE Controller
)
{
CONST DT_SOCKET_BINDING * pEnd;
DT_SERVICE * pService;
CONST DT_SOCKET_BINDING * pSocketBinding;
UINT8 * pBuffer;
CONST ESL_SOCKET_BINDING * pEnd;
ESL_PORT * pPort;
ESL_SERVICE * pPreviousService;
ESL_SERVICE * pService;
ESL_SERVICE ** ppServiceListHead;
CONST ESL_SOCKET_BINDING * pSocketBinding;
EFI_STATUS Status;
EFI_TPL TplPrevious;
@@ -310,9 +322,54 @@ EslServiceDisconnect (
RAISE_TPL ( TplPrevious, TPL_SOCKETS );
//
// Shutdown the service
// Walk the list of ports
//
pSocketBinding->pfnShutdown ( pService );
pPort = pService->pPortList;
while ( NULL != pPort ) {
//
// Remove the port from the port list
//
pPort->pService = NULL;
pService->pPortList = pPort->pLinkService;
//
// Close the port
//
EslSocketPortCloseStart ( pPort,
TRUE,
DEBUG_POOL | DEBUG_INIT );
//
// Set the next port
//
pPort = pService->pPortList;
}
//
// Remove the service from the service list
//
pBuffer = (UINT8 *)&mEslLayer;
pBuffer = &pBuffer[ pService->pSocketBinding->ServiceListOffset ];
ppServiceListHead = (ESL_SERVICE **)pBuffer;
pPreviousService = *ppServiceListHead;
if ( pService == pPreviousService ) {
//
// Remove the service from the beginning of the list
//
*ppServiceListHead = pService->pNext;
}
else {
//
// Remove the service from the middle of the list
//
while ( NULL != pPreviousService ) {
if ( pService == pPreviousService->pNext ) {
pPreviousService->pNext = pService->pNext;
break;
}
pPreviousService = pPreviousService->pNext;
}
}
//
// Release the socket layer synchronization
@@ -387,48 +444,6 @@ EslServiceDisconnect (
/**
Install the socket service
@param [in] pImageHandle Address of the image handle
@retval EFI_SUCCESS Service installed successfully
**/
EFI_STATUS
EFIAPI
EslServiceInstall (
IN EFI_HANDLE * pImageHandle
)
{
EFI_STATUS Status;
//
// Install the socket service binding protocol
//
Status = gBS->InstallMultipleProtocolInterfaces (
pImageHandle,
&gEfiSocketServiceBindingProtocolGuid,
&mEslLayer.ServiceBinding,
NULL
);
if ( !EFI_ERROR ( Status )) {
DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,
"Installed: gEfiSocketServiceBindingProtocolGuid on 0x%08x\r\n",
*pImageHandle ));
}
else {
DEBUG (( DEBUG_ERROR | DEBUG_POOL | DEBUG_INIT,
"ERROR - InstallMultipleProtocolInterfaces failed, Status: %r\r\n",
Status ));
}
//
// Return the operation status
//
return Status;
}
/**
Initialize the service layer
@@ -441,69 +456,20 @@ EslServiceLoad (
IN EFI_HANDLE ImageHandle
)
{
DT_LAYER * pLayer;
ESL_LAYER * pLayer;
//
// Save the image handle
//
pLayer = &mEslLayer;
ZeroMem ( pLayer, sizeof ( *pLayer ));
pLayer->Signature = LAYER_SIGNATURE;
pLayer->ImageHandle = ImageHandle;
//
// Initialize the TCP4 close
//
pLayer->TcpCloseMax4 = DIM ( mpEfiTcpClose4 );
pLayer->ppTcpClose4 = mpEfiTcpClose4;
//
// Connect the service binding protocol to the image handle
//
pLayer->ServiceBinding.CreateChild = EslSocketCreateChild;
pLayer->ServiceBinding.DestroyChild = EslSocketDestroyChild;
}
/**
Uninstall the socket service
@param [in] ImageHandle Handle for the image.
@retval EFI_SUCCESS Service installed successfully
**/
EFI_STATUS
EFIAPI
EslServiceUninstall (
IN EFI_HANDLE ImageHandle
)
{
EFI_STATUS Status;
//
// Install the socket service binding protocol
//
Status = gBS->UninstallMultipleProtocolInterfaces (
ImageHandle,
&gEfiSocketServiceBindingProtocolGuid,
&mEslLayer.ServiceBinding,
NULL
);
if ( !EFI_ERROR ( Status )) {
DEBUG (( DEBUG_POOL | DEBUG_INIT,
"Removed: gEfiSocketServiceBindingProtocolGuid from 0x%08x\r\n",
ImageHandle ));
}
else {
DEBUG (( DEBUG_ERROR | DEBUG_POOL | DEBUG_INIT,
"ERROR - Failed to remove gEfiSocketServiceBindingProtocolGuid from 0x%08x, Status: %r\r\n",
ImageHandle,
Status ));
}
//
// Return the operation status
//
return Status;
pLayer->pServiceBinding = &mEfiServiceBinding;
}
@@ -517,13 +483,12 @@ EslServiceUnload (
VOID
)
{
DT_LAYER * pLayer;
ESL_LAYER * pLayer;
//
// Undo the work by ServiceLoad
//
pLayer = &mEslLayer;
pLayer->ImageHandle = NULL;
pLayer->ServiceBinding.CreateChild = NULL;
pLayer->ServiceBinding.DestroyChild = NULL;
pLayer->pServiceBinding = NULL;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -15,14 +15,30 @@
#include "Socket.h"
CONST EFI_GUID mEslRawServiceGuid = {
0xc31bf4a5, 0x2c7, 0x49d2, { 0xa5, 0x58, 0xfe, 0x62, 0x6f, 0x7e, 0xd4, 0x77 }
/**
The following GUID values are only used when an application links
against EfiSocketLib. An alternative set of values exists in
SocketDxe\EntryUnload.c which the SocketDxe driver uses to coexist
with socket applications.
Tag GUID - IPv4 in use by an application using EfiSocketLib
**/
CONST EFI_GUID mEslIp4ServiceGuid = {
0x9c756011, 0x5d44, 0x4ee0, { 0xbc, 0xe7, 0xc3, 0x82, 0x18, 0xfe, 0x39, 0x8d }
};
/**
Tag GUID - TCPv4 in use by an application using EfiSocketLib
**/
CONST EFI_GUID mEslTcp4ServiceGuid = {
0xffc659c2, 0x4ef2, 0x4532, { 0xb8, 0x75, 0xcd, 0x9a, 0xa4, 0x27, 0x4c, 0xde }
};
/**
Tag GUID - UDPv4 in use by an application using EfiSocketLib
**/
CONST EFI_GUID mEslUdp4ServiceGuid = {
0x44e03a55, 0x8d97, 0x4511, { 0xbf, 0xef, 0xa, 0x8b, 0xc6, 0x2c, 0x25, 0xae }
};
@@ -31,10 +47,20 @@ CONST EFI_GUID mEslUdp4ServiceGuid = {
/**
Connect to the EFI socket library
@param [in] ppSocketProtocol Address to receive the socket protocol address
This routine creates the ::ESL_SOCKET structure and returns
the API (::EFI_SOCKET_PROTOCOL address) to the socket file
system layer in BsdSocketLib.
This routine is called from the ::socket routine in BsdSocketLib
to create the data structure and initialize the API for a socket.
Note that this implementation is only used by socket applications
that link directly to EslSocketLib.
@param [in] ppSocketProtocol Address to receive the ::EFI_SOCKET_PROTOCOL
structure address
@return Value for ::errno, zero (0) indicates success.
@retval 0 Successfully returned the socket protocol
@retval other Value for errno
**/
int
EslServiceGetProtocol (
@@ -42,7 +68,7 @@ EslServiceGetProtocol (
)
{
EFI_HANDLE ChildHandle;
DT_SOCKET * pSocket;
ESL_SOCKET * pSocket;
int RetVal;
EFI_STATUS Status;
@@ -81,6 +107,16 @@ EslServiceGetProtocol (
/**
Connect to the network layer
This routine is the constructor for the EfiSocketLib when the
library is linked directly to an application. This routine
walks the ::cEslSocketBinding table to create ::ESL_SERVICE
structures, associated with the network adapters, which this
routine links to the ::ESL_LAYER structure.
This routine is called from ::EslConstructor as a result of the
constructor redirection in ::mpfnEslConstructor at the end of this
file.
@retval EFI_SUCCESS Successfully connected to the network layer
**/
@@ -89,11 +125,12 @@ EslServiceNetworkConnect (
VOID
)
{
BOOLEAN bSomethingFound;
UINTN HandleCount;
EFI_HANDLE * pHandles;
UINTN Index;
CONST DT_SOCKET_BINDING * pSocketBinding;
CONST DT_SOCKET_BINDING * pEnd;
CONST ESL_SOCKET_BINDING * pEnd;
EFI_HANDLE * pHandles;
CONST ESL_SOCKET_BINDING * pSocketBinding;
EFI_STATUS Status;
DBG_ENTER ( );
@@ -102,13 +139,14 @@ EslServiceNetworkConnect (
// Initialize the socket layer
//
Status = EFI_SUCCESS;
bSomethingFound = FALSE;
EslServiceLoad ( gImageHandle );
//
// Connect the network devices
//
pSocketBinding = &cEslSocketBinding [0];
pEnd = &pSocketBinding [ cEslSocketBindingEntries ];
pSocketBinding = &cEslSocketBinding[0];
pEnd = &pSocketBinding[ cEslSocketBindingEntries ];
while ( pEnd > pSocketBinding ) {
//
// Attempt to locate the network adapters
@@ -121,24 +159,30 @@ EslServiceNetworkConnect (
&HandleCount,
&pHandles );
if ( EFI_ERROR ( Status )) {
break;
DEBUG (( DEBUG_ERROR,
"ERROR with %s layer, Status: %r\r\n",
pSocketBinding->pName,
Status ));
}
if ( NULL != pHandles ) {
//
// Attempt to connect to this network adapter
//
for ( Index = 0; HandleCount > Index; Index++ ) {
Status = EslServiceConnect ( gImageHandle,
pHandles [ Index ]);
if ( EFI_ERROR ( Status )) {
break;
else {
if ( NULL != pHandles ) {
//
// Attempt to connect to this network adapter
//
for ( Index = 0; HandleCount > Index; Index++ ) {
Status = EslServiceConnect ( gImageHandle,
pHandles[ Index ]);
if ( EFI_ERROR ( Status )) {
break;
}
bSomethingFound = TRUE;
}
}
//
// Done with the handles
//
gBS->FreePool ( pHandles );
//
// Done with the handles
//
gBS->FreePool ( pHandles );
}
}
//
@@ -150,6 +194,9 @@ EslServiceNetworkConnect (
//
// Return the network connection status
//
if ( bSomethingFound ) {
Status = EFI_SUCCESS;
}
DBG_EXIT_STATUS ( Status );
return Status;
}
@@ -158,6 +205,15 @@ EslServiceNetworkConnect (
/**
Disconnect from the network layer
Destructor for the EfiSocketLib when the library is linked
directly to an application. This routine walks the
::cEslSocketBinding table to remove the ::ESL_SERVICE
structures (network connections) from the ::ESL_LAYER structure.
This routine is called from ::EslDestructor as a result of the
destructor redirection in ::mpfnEslDestructor at the end of this
file.
@retval EFI_SUCCESS Successfully disconnected from the network layer
**/
@@ -167,10 +223,10 @@ EslServiceNetworkDisconnect (
)
{
UINTN HandleCount;
EFI_HANDLE * pHandles;
UINTN Index;
CONST DT_SOCKET_BINDING * pSocketBinding;
CONST DT_SOCKET_BINDING * pEnd;
CONST ESL_SOCKET_BINDING * pEnd;
EFI_HANDLE * pHandles;
CONST ESL_SOCKET_BINDING * pSocketBinding;
EFI_STATUS Status;
DBG_ENTER ( );
@@ -183,8 +239,8 @@ EslServiceNetworkDisconnect (
//
// Disconnect the network devices
//
pSocketBinding = &cEslSocketBinding [0];
pEnd = &pSocketBinding [ cEslSocketBindingEntries ];
pSocketBinding = &cEslSocketBinding[0];
pEnd = &pSocketBinding[ cEslSocketBindingEntries ];
while ( pEnd > pSocketBinding ) {
//
// Attempt to locate the network adapters
@@ -205,7 +261,7 @@ EslServiceNetworkDisconnect (
//
for ( Index = 0; HandleCount > Index; Index++ ) {
Status = EslServiceDisconnect ( gImageHandle,
pHandles [ Index ]);
pHandles[ Index ]);
if ( EFI_ERROR ( Status )) {
break;
}
@@ -238,5 +294,19 @@ EslServiceNetworkDisconnect (
}
PFN_ESL_xSTRUCTOR mpfnEslConstructor = EslServiceNetworkConnect;
PFN_ESL_xSTRUCTOR mpfnEslDestructor = EslServiceNetworkDisconnect;
/**
Socket layer's service binding protocol delcaration.
**/
CONST EFI_SERVICE_BINDING_PROTOCOL mEfiServiceBinding = {
NULL,
NULL
};
/**
The following entries redirect the constructor and destructor
for any socket application that links against the EfiSocketLib.
Note that the SocketDxe driver uses different redirection.
**/
PFN_ESL_xSTRUCTOR mpfnEslConstructor = EslServiceNetworkConnect; ///< Constructor for EfiSocketLib
PFN_ESL_xSTRUCTOR mpfnEslDestructor = EslServiceNetworkDisconnect; ///< Destructor for EfiSocketLib