]> git.proxmox.com Git - mirror_edk2.git/blob - StdLib/EfiSocketLib/UseEfiSocketLib.c
e44a7204355cf0db2a26b4cdcec0e600118ec219
[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 __attribute__((weak)) = {
27 0x9c756011, 0x5d44, 0x4ee0, { 0xbc, 0xe7, 0xc3, 0x82, 0x18, 0xfe, 0x39, 0x8d }
28 };
29
30
31 /**
32 Tag GUID - IPv6 in use by an application using EfiSocketLib
33 **/
34 CONST EFI_GUID mEslIp6ServiceGuid __attribute__((weak)) = {
35 0xc51b2761, 0xc476, 0x45fe, { 0xbe, 0x61, 0xba, 0x4b, 0xcc, 0x32, 0xf2, 0x34 }
36 };
37
38
39 /**
40 Tag GUID - TCPv4 in use by an application using EfiSocketLib
41 **/
42 CONST EFI_GUID mEslTcp4ServiceGuid __attribute__((weak)) = {
43 0xffc659c2, 0x4ef2, 0x4532, { 0xb8, 0x75, 0xcd, 0x9a, 0xa4, 0x27, 0x4c, 0xde }
44 };
45
46
47 /**
48 Tag GUID - TCPv6 in use by an application using EfiSocketLib
49 **/
50 CONST EFI_GUID mEslTcp6ServiceGuid __attribute__((weak)) = {
51 0x279858a4, 0x4e9e, 0x4e53, { 0x93, 0x22, 0xf2, 0x54, 0xe0, 0x7e, 0xef, 0xd4 }
52 };
53
54
55 /**
56 Tag GUID - UDPv4 in use by an application using EfiSocketLib
57 **/
58 CONST EFI_GUID mEslUdp4ServiceGuid __attribute__((weak)) = {
59 0x44e03a55, 0x8d97, 0x4511, { 0xbf, 0xef, 0xa, 0x8b, 0xc6, 0x2c, 0x25, 0xae }
60 };
61
62
63 /**
64 Tag GUID - UDPv6 in use by an application using EfiSocketLib
65 **/
66 CONST EFI_GUID mEslUdp6ServiceGuid __attribute__((weak)) = {
67 0xaa4af677, 0x6efe, 0x477c, { 0x96, 0x68, 0xe8, 0x13, 0x9d, 0x2, 0xfd, 0x9b }
68 };
69
70
71 /**
72 Connect to the EFI socket library
73
74 This routine creates the ::ESL_SOCKET structure and returns
75 the API (::EFI_SOCKET_PROTOCOL address) to the socket file
76 system layer in BsdSocketLib.
77
78 This routine is called from the ::socket routine in BsdSocketLib
79 to create the data structure and initialize the API for a socket.
80 Note that this implementation is only used by socket applications
81 that link directly to EslSocketLib.
82
83 @param [in] ppSocketProtocol Address to receive the ::EFI_SOCKET_PROTOCOL
84 structure address
85
86 @return Value for ::errno, zero (0) indicates success.
87
88 **/
89 int
90 EslServiceGetProtocol (
91 IN EFI_SOCKET_PROTOCOL ** ppSocketProtocol
92 )
93 {
94 EFI_HANDLE ChildHandle;
95 ESL_SOCKET * pSocket;
96 int RetVal;
97 EFI_STATUS Status;
98
99 DBG_ENTER ( );
100
101 //
102 // Assume success
103 //
104 RetVal = 0;
105
106 //
107 // Locate the socket protocol
108 //
109 ChildHandle = NULL;
110 Status = EslSocketAllocate ( &ChildHandle,
111 DEBUG_SOCKET,
112 &pSocket );
113 if ( !EFI_ERROR ( Status )) {
114 *ppSocketProtocol = &pSocket->SocketProtocol;
115 }
116 else {
117 //
118 // No resources
119 //
120 RetVal = ENOMEM;
121 }
122
123 //
124 // Return the operation status
125 //
126 DBG_EXIT_DEC ( RetVal );
127 return RetVal;
128 }
129
130
131 /**
132 Connect to the network layer
133
134 This routine is the constructor for the EfiSocketLib when the
135 library is linked directly to an application. This routine
136 walks the ::cEslSocketBinding table to create ::ESL_SERVICE
137 structures, associated with the network adapters, which this
138 routine links to the ::ESL_LAYER structure.
139
140 This routine is called from ::EslConstructor as a result of the
141 constructor redirection in ::mpfnEslConstructor at the end of this
142 file.
143
144 @retval EFI_SUCCESS Successfully connected to the network layer
145
146 **/
147 EFI_STATUS
148 EslServiceNetworkConnect (
149 VOID
150 )
151 {
152 BOOLEAN bSomethingFound;
153 UINTN HandleCount;
154 UINTN Index;
155 CONST ESL_SOCKET_BINDING * pEnd;
156 EFI_HANDLE * pHandles;
157 CONST ESL_SOCKET_BINDING * pSocketBinding;
158 EFI_STATUS Status;
159
160 DBG_ENTER ( );
161
162 //
163 // Initialize the socket layer
164 //
165 Status = EFI_SUCCESS;
166 bSomethingFound = FALSE;
167 EslServiceLoad ( gImageHandle );
168
169 //
170 // Connect the network devices
171 //
172 pSocketBinding = &cEslSocketBinding[0];
173 pEnd = &pSocketBinding[ cEslSocketBindingEntries ];
174 while ( pEnd > pSocketBinding ) {
175 //
176 // Attempt to locate the network adapters
177 //
178 HandleCount = 0;
179 pHandles = NULL;
180 Status = gBS->LocateHandleBuffer ( ByProtocol,
181 pSocketBinding->pNetworkBinding,
182 NULL,
183 &HandleCount,
184 &pHandles );
185 if ( EFI_ERROR ( Status )) {
186 DEBUG (( DEBUG_ERROR,
187 "ERROR with %s layer, Status: %r\r\n",
188 pSocketBinding->pName,
189 Status ));
190 }
191 else {
192 if ( NULL != pHandles ) {
193 //
194 // Attempt to connect to this network adapter
195 //
196 for ( Index = 0; HandleCount > Index; Index++ ) {
197 Status = EslServiceConnect ( gImageHandle,
198 pHandles[ Index ]);
199 if ( !EFI_ERROR ( Status )) {
200 bSomethingFound = TRUE;
201 }
202 else {
203 if ( EFI_OUT_OF_RESOURCES == Status ) {
204 //
205 // Pointless to continue without memory
206 //
207 break;
208 }
209 }
210 }
211
212 //
213 // Done with the handles
214 //
215 gBS->FreePool ( pHandles );
216 }
217 }
218
219 //
220 // Set the next network protocol
221 //
222 pSocketBinding += 1;
223 }
224
225 //
226 // Return the network connection status
227 //
228 if ( bSomethingFound ) {
229 Status = EFI_SUCCESS;
230 }
231 DBG_EXIT_STATUS ( Status );
232 return Status;
233 }
234
235
236 /**
237 Disconnect from the network layer
238
239 Destructor for the EfiSocketLib when the library is linked
240 directly to an application. This routine walks the
241 ::cEslSocketBinding table to remove the ::ESL_SERVICE
242 structures (network connections) from the ::ESL_LAYER structure.
243
244 This routine is called from ::EslDestructor as a result of the
245 destructor redirection in ::mpfnEslDestructor at the end of this
246 file.
247
248 @retval EFI_SUCCESS Successfully disconnected from the network layer
249
250 **/
251 EFI_STATUS
252 EslServiceNetworkDisconnect (
253 VOID
254 )
255 {
256 UINTN HandleCount;
257 UINTN Index;
258 CONST ESL_SOCKET_BINDING * pEnd;
259 EFI_HANDLE * pHandles;
260 CONST ESL_SOCKET_BINDING * pSocketBinding;
261 EFI_STATUS Status;
262
263 DBG_ENTER ( );
264
265 //
266 // Assume success
267 //
268 Status = EFI_SUCCESS;
269
270 //
271 // Disconnect the network devices
272 //
273 pSocketBinding = &cEslSocketBinding[0];
274 pEnd = &pSocketBinding[ cEslSocketBindingEntries ];
275 while ( pEnd > pSocketBinding ) {
276 //
277 // Attempt to locate the network adapters
278 //
279 HandleCount = 0;
280 pHandles = NULL;
281 Status = gBS->LocateHandleBuffer ( ByProtocol,
282 pSocketBinding->pNetworkBinding,
283 NULL,
284 &HandleCount,
285 &pHandles );
286 if (( !EFI_ERROR ( Status ))
287 && ( NULL != pHandles )) {
288 //
289 // Attempt to disconnect from this network adapter
290 //
291 for ( Index = 0; HandleCount > Index; Index++ ) {
292 Status = EslServiceDisconnect ( gImageHandle,
293 pHandles[ Index ]);
294 if ( EFI_ERROR ( Status )) {
295 break;
296 }
297 }
298
299 //
300 // Done with the handles
301 //
302 gBS->FreePool ( pHandles );
303 }
304
305 //
306 // Set the next network protocol
307 //
308 pSocketBinding += 1;
309 Status = EFI_SUCCESS;
310 }
311
312 //
313 // Finish the disconnect operation
314 //
315 if ( !EFI_ERROR ( Status )) {
316 EslServiceUnload ( );
317 }
318
319 //
320 // Return the network connection status
321 //
322 DBG_EXIT_STATUS ( Status );
323 return Status;
324 }
325
326
327 /**
328 Socket layer's service binding protocol delcaration.
329 **/
330 CONST EFI_SERVICE_BINDING_PROTOCOL mEfiServiceBinding __attribute__((weak)) = {
331 NULL,
332 NULL
333 };
334
335
336 /**
337 The following entries redirect the constructor and destructor
338 for any socket application that links against the EfiSocketLib.
339 Note that the SocketDxe driver uses different redirection.
340 **/
341 PFN_ESL_xSTRUCTOR mpfnEslConstructor __attribute__((weak)) = EslServiceNetworkConnect; ///< Constructor for EfiSocketLib
342 PFN_ESL_xSTRUCTOR mpfnEslDestructor __attribute__((weak)) = EslServiceNetworkDisconnect; ///< Destructor for EfiSocketLib