]> git.proxmox.com Git - mirror_edk2.git/blob - StdLib/EfiSocketLib/UseEfiSocketLib.c
MdeModulePkg PCI Bus Driver: Remove the workaround for the EFI_PCI_IO_ATTRIBUTE_VGA_P...
[mirror_edk2.git] / StdLib / EfiSocketLib / UseEfiSocketLib.c
1 /** @file
2 Implement the connection to the EFI socket library
3
4 Copyright (c) 2011, Intel Corporation
5 All rights reserved. This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
9
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12
13 **/
14
15 #include "Socket.h"
16
17
18 /**
19 The following GUID values are only used when an application links
20 against EfiSocketLib. An alternative set of values exists in
21 SocketDxe\EntryUnload.c which the SocketDxe driver uses to coexist
22 with socket applications.
23
24 Tag GUID - IPv4 in use by an application using EfiSocketLib
25 **/
26 CONST EFI_GUID mEslIp4ServiceGuid = {
27 0x9c756011, 0x5d44, 0x4ee0, { 0xbc, 0xe7, 0xc3, 0x82, 0x18, 0xfe, 0x39, 0x8d }
28 };
29
30
31 /**
32 Tag GUID - TCPv4 in use by an application using EfiSocketLib
33 **/
34 CONST EFI_GUID mEslTcp4ServiceGuid = {
35 0xffc659c2, 0x4ef2, 0x4532, { 0xb8, 0x75, 0xcd, 0x9a, 0xa4, 0x27, 0x4c, 0xde }
36 };
37
38
39 /**
40 Tag GUID - UDPv4 in use by an application using EfiSocketLib
41 **/
42 CONST EFI_GUID mEslUdp4ServiceGuid = {
43 0x44e03a55, 0x8d97, 0x4511, { 0xbf, 0xef, 0xa, 0x8b, 0xc6, 0x2c, 0x25, 0xae }
44 };
45
46
47 /**
48 Connect to the EFI socket library
49
50 This routine creates the ::ESL_SOCKET structure and returns
51 the API (::EFI_SOCKET_PROTOCOL address) to the socket file
52 system layer in BsdSocketLib.
53
54 This routine is called from the ::socket routine in BsdSocketLib
55 to create the data structure and initialize the API for a socket.
56 Note that this implementation is only used by socket applications
57 that link directly to EslSocketLib.
58
59 @param [in] ppSocketProtocol Address to receive the ::EFI_SOCKET_PROTOCOL
60 structure address
61
62 @return Value for ::errno, zero (0) indicates success.
63
64 **/
65 int
66 EslServiceGetProtocol (
67 IN EFI_SOCKET_PROTOCOL ** ppSocketProtocol
68 )
69 {
70 EFI_HANDLE ChildHandle;
71 ESL_SOCKET * pSocket;
72 int RetVal;
73 EFI_STATUS Status;
74
75 DBG_ENTER ( );
76
77 //
78 // Assume success
79 //
80 RetVal = 0;
81
82 //
83 // Locate the socket protocol
84 //
85 ChildHandle = NULL;
86 Status = EslSocketAllocate ( &ChildHandle,
87 DEBUG_SOCKET,
88 &pSocket );
89 if ( !EFI_ERROR ( Status )) {
90 *ppSocketProtocol = &pSocket->SocketProtocol;
91 }
92 else {
93 //
94 // No resources
95 //
96 RetVal = ENOMEM;
97 }
98
99 //
100 // Return the operation status
101 //
102 DBG_EXIT_DEC ( RetVal );
103 return RetVal;
104 }
105
106
107 /**
108 Connect to the network layer
109
110 This routine is the constructor for the EfiSocketLib when the
111 library is linked directly to an application. This routine
112 walks the ::cEslSocketBinding table to create ::ESL_SERVICE
113 structures, associated with the network adapters, which this
114 routine links to the ::ESL_LAYER structure.
115
116 This routine is called from ::EslConstructor as a result of the
117 constructor redirection in ::mpfnEslConstructor at the end of this
118 file.
119
120 @retval EFI_SUCCESS Successfully connected to the network layer
121
122 **/
123 EFI_STATUS
124 EslServiceNetworkConnect (
125 VOID
126 )
127 {
128 BOOLEAN bSomethingFound;
129 UINTN HandleCount;
130 UINTN Index;
131 CONST ESL_SOCKET_BINDING * pEnd;
132 EFI_HANDLE * pHandles;
133 CONST ESL_SOCKET_BINDING * pSocketBinding;
134 EFI_STATUS Status;
135
136 DBG_ENTER ( );
137
138 //
139 // Initialize the socket layer
140 //
141 Status = EFI_SUCCESS;
142 bSomethingFound = FALSE;
143 EslServiceLoad ( gImageHandle );
144
145 //
146 // Connect the network devices
147 //
148 pSocketBinding = &cEslSocketBinding[0];
149 pEnd = &pSocketBinding[ cEslSocketBindingEntries ];
150 while ( pEnd > pSocketBinding ) {
151 //
152 // Attempt to locate the network adapters
153 //
154 HandleCount = 0;
155 pHandles = NULL;
156 Status = gBS->LocateHandleBuffer ( ByProtocol,
157 pSocketBinding->pNetworkBinding,
158 NULL,
159 &HandleCount,
160 &pHandles );
161 if ( EFI_ERROR ( Status )) {
162 DEBUG (( DEBUG_ERROR,
163 "ERROR with %s layer, Status: %r\r\n",
164 pSocketBinding->pName,
165 Status ));
166 }
167 else {
168 if ( NULL != pHandles ) {
169 //
170 // Attempt to connect to this network adapter
171 //
172 for ( Index = 0; HandleCount > Index; Index++ ) {
173 Status = EslServiceConnect ( gImageHandle,
174 pHandles[ Index ]);
175 if ( EFI_ERROR ( Status )) {
176 break;
177 }
178 bSomethingFound = TRUE;
179 }
180
181 //
182 // Done with the handles
183 //
184 gBS->FreePool ( pHandles );
185 }
186 }
187
188 //
189 // Set the next network protocol
190 //
191 pSocketBinding += 1;
192 }
193
194 //
195 // Return the network connection status
196 //
197 if ( bSomethingFound ) {
198 Status = EFI_SUCCESS;
199 }
200 DBG_EXIT_STATUS ( Status );
201 return Status;
202 }
203
204
205 /**
206 Disconnect from the network layer
207
208 Destructor for the EfiSocketLib when the library is linked
209 directly to an application. This routine walks the
210 ::cEslSocketBinding table to remove the ::ESL_SERVICE
211 structures (network connections) from the ::ESL_LAYER structure.
212
213 This routine is called from ::EslDestructor as a result of the
214 destructor redirection in ::mpfnEslDestructor at the end of this
215 file.
216
217 @retval EFI_SUCCESS Successfully disconnected from the network layer
218
219 **/
220 EFI_STATUS
221 EslServiceNetworkDisconnect (
222 VOID
223 )
224 {
225 UINTN HandleCount;
226 UINTN Index;
227 CONST ESL_SOCKET_BINDING * pEnd;
228 EFI_HANDLE * pHandles;
229 CONST ESL_SOCKET_BINDING * pSocketBinding;
230 EFI_STATUS Status;
231
232 DBG_ENTER ( );
233
234 //
235 // Assume success
236 //
237 Status = EFI_SUCCESS;
238
239 //
240 // Disconnect the network devices
241 //
242 pSocketBinding = &cEslSocketBinding[0];
243 pEnd = &pSocketBinding[ cEslSocketBindingEntries ];
244 while ( pEnd > pSocketBinding ) {
245 //
246 // Attempt to locate the network adapters
247 //
248 HandleCount = 0;
249 pHandles = NULL;
250 Status = gBS->LocateHandleBuffer ( ByProtocol,
251 pSocketBinding->pNetworkBinding,
252 NULL,
253 &HandleCount,
254 &pHandles );
255 if ( EFI_ERROR ( Status )) {
256 break;
257 }
258 if ( NULL != pHandles ) {
259 //
260 // Attempt to disconnect from this network adapter
261 //
262 for ( Index = 0; HandleCount > Index; Index++ ) {
263 Status = EslServiceDisconnect ( gImageHandle,
264 pHandles[ Index ]);
265 if ( EFI_ERROR ( Status )) {
266 break;
267 }
268 }
269
270 //
271 // Done with the handles
272 //
273 gBS->FreePool ( pHandles );
274 }
275
276 //
277 // Set the next network protocol
278 //
279 pSocketBinding += 1;
280 }
281
282 //
283 // Finish the disconnect operation
284 //
285 if ( !EFI_ERROR ( Status )) {
286 EslServiceUnload ( );
287 }
288
289 //
290 // Return the network connection status
291 //
292 DBG_EXIT_STATUS ( Status );
293 return Status;
294 }
295
296
297 /**
298 Socket layer's service binding protocol delcaration.
299 **/
300 CONST EFI_SERVICE_BINDING_PROTOCOL mEfiServiceBinding = {
301 NULL,
302 NULL
303 };
304
305
306 /**
307 The following entries redirect the constructor and destructor
308 for any socket application that links against the EfiSocketLib.
309 Note that the SocketDxe driver uses different redirection.
310 **/
311 PFN_ESL_xSTRUCTOR mpfnEslConstructor = EslServiceNetworkConnect; ///< Constructor for EfiSocketLib
312 PFN_ESL_xSTRUCTOR mpfnEslDestructor = EslServiceNetworkDisconnect; ///< Destructor for EfiSocketLib