]>
Commit | Line | Data |
---|---|---|
7e7b729f AC |
1 | /** @file\r |
2 | \r | |
3 | The implementation of EFI Redfidh Discover Protocol.\r | |
4 | \r | |
5 | (C) Copyright 2021 Hewlett Packard Enterprise Development LP<BR>\r | |
f7da805b | 6 | Copyright (c) 2022, AMD Incorporated. All rights reserved.\r |
7e7b729f AC |
7 | \r |
8 | SPDX-License-Identifier: BSD-2-Clause-Patent\r | |
9 | \r | |
10 | **/\r | |
11 | \r | |
12 | #include "RedfishDiscoverInternal.h"\r | |
13 | \r | |
39de741e MK |
14 | LIST_ENTRY mRedfishDiscoverList;\r |
15 | LIST_ENTRY mRedfishInstanceList;\r | |
16 | EFI_SMBIOS_PROTOCOL *mSmbios = NULL;\r | |
7e7b729f | 17 | \r |
39de741e MK |
18 | UINTN mNumNetworkInterface = 0;\r |
19 | UINTN mNumRestExInstance = 0;\r | |
20 | LIST_ENTRY mEfiRedfishDiscoverNetworkInterface;\r | |
21 | LIST_ENTRY mEfiRedfishDiscoverRestExInstance;\r | |
7e7b729f | 22 | \r |
39de741e MK |
23 | EFI_GUID mRedfishDiscoverTcp4InstanceGuid = EFI_REDFISH_DISCOVER_TCP4_INSTANCE_GUID;\r |
24 | EFI_GUID mRedfishDiscoverTcp6InstanceGuid = EFI_REDFISH_DISCOVER_TCP6_INSTANCE_GUID;\r | |
25 | EFI_GUID mRedfishDiscoverRestExInstanceGuid = EFI_REDFISH_DISCOVER_REST_EX_INSTANCE_GUID;\r | |
7e7b729f | 26 | \r |
7e7b729f AC |
27 | EFI_STATUS\r |
28 | EFIAPI\r | |
29 | Tcp4GetSubnetInfo (\r | |
39de741e MK |
30 | IN EFI_HANDLE ImageHandle,\r |
31 | IN EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *Instance\r | |
32 | );\r | |
7e7b729f AC |
33 | \r |
34 | EFI_STATUS\r | |
35 | EFIAPI\r | |
36 | Tcp6GetSubnetInfo (\r | |
39de741e MK |
37 | IN EFI_HANDLE ImageHandle,\r |
38 | IN EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *Instance\r | |
39 | );\r | |
7e7b729f | 40 | \r |
39de741e | 41 | static REDFISH_DISCOVER_REQUIRED_PROTOCOL gRequiredProtocol[] = {\r |
7e7b729f AC |
42 | {\r |
43 | ProtocolTypeTcp4,\r | |
44 | L"TCP4 Service Binding Protocol",\r | |
45 | &gEfiTcp4ProtocolGuid,\r | |
46 | &gEfiTcp4ServiceBindingProtocolGuid,\r | |
47 | &mRedfishDiscoverTcp4InstanceGuid,\r | |
48 | Tcp4GetSubnetInfo\r | |
49 | },\r | |
50 | {\r | |
51 | ProtocolTypeTcp6,\r | |
52 | L"TCP6 Service Binding Protocol",\r | |
53 | &gEfiTcp6ProtocolGuid,\r | |
54 | &gEfiTcp6ServiceBindingProtocolGuid,\r | |
55 | &mRedfishDiscoverTcp6InstanceGuid,\r | |
56 | Tcp6GetSubnetInfo\r | |
57 | },\r | |
58 | {\r | |
59 | ProtocolTypeRestEx,\r | |
60 | L"REST EX Service Binding Protocol",\r | |
61 | &gEfiRestExProtocolGuid,\r | |
62 | &gEfiRestExServiceBindingProtocolGuid,\r | |
63 | &mRedfishDiscoverRestExInstanceGuid,\r | |
64 | NULL\r | |
65 | }\r | |
66 | };\r | |
67 | \r | |
68 | /**\r | |
69 | This function creates REST EX instance for the found Resfish service.\r | |
70 | by known owner handle.\r | |
71 | \r | |
72 | @param[in] Instance EFI_REDFISH_DISCOVERED_INTERNAL_INSTANCE\r | |
73 | @param[in] Token Client token.\r | |
74 | \r | |
75 | @retval NULL Instance not found.\r | |
76 | @retval EFI_REDFISH_DISCOVERED_INTERNAL_INSTANCE The instance owned by this owner.\r | |
77 | \r | |
78 | **/\r | |
79 | EFI_STATUS\r | |
80 | CreateRestExInstance (\r | |
39de741e MK |
81 | IN EFI_REDFISH_DISCOVERED_INTERNAL_INSTANCE *Instance,\r |
82 | IN EFI_REDFISH_DISCOVERED_TOKEN *Token\r | |
7e7b729f AC |
83 | )\r |
84 | {\r | |
39de741e | 85 | EFI_STATUS Status;\r |
7e7b729f AC |
86 | \r |
87 | Status = RestExLibCreateChild (\r | |
39de741e MK |
88 | Instance->Owner,\r |
89 | FixedPcdGetBool (PcdRedfishDiscoverAccessModeInBand) ? EfiRestExServiceInBandAccess : EfiRestExServiceOutOfBandAccess,\r | |
90 | EfiRestExConfigHttp,\r | |
91 | EfiRestExServiceRedfish,\r | |
92 | &Token->DiscoverList.RedfishInstances->Information.RedfishRestExHandle\r | |
93 | );\r | |
7e7b729f AC |
94 | return Status;\r |
95 | }\r | |
96 | \r | |
97 | /**\r | |
98 | This function gets EFI_REDFISH_DISCOVERED_INTERNAL_INSTANCE\r | |
99 | by known owner handle.\r | |
100 | \r | |
101 | @param[in] ImageHandle Image handle owns EFI_REDFISH_DISCOVERED_INTERNAL_INSTANCE.\r | |
102 | @param[in] TargetNetworkInterface Target network interface used by this EFI_REDFISH_DISCOVERED_INTERNAL_INSTANCE.\r | |
103 | @param[in] DiscoverFlags EFI_REDFISH_DISCOVER_FLAG\r | |
104 | \r | |
105 | @retval NULL Instance not found.\r | |
106 | @retval EFI_REDFISH_DISCOVERED_INTERNAL_INSTANCE The instance owned by this owner.\r | |
107 | \r | |
108 | **/\r | |
109 | EFI_REDFISH_DISCOVERED_INTERNAL_INSTANCE *\r | |
110 | GetInstanceByOwner (\r | |
39de741e MK |
111 | IN EFI_HANDLE ImageHandle,\r |
112 | IN EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *TargetNetworkInterface,\r | |
113 | IN EFI_REDFISH_DISCOVER_FLAG DiscoverFlags\r | |
7e7b729f AC |
114 | )\r |
115 | {\r | |
39de741e | 116 | EFI_REDFISH_DISCOVERED_INTERNAL_INSTANCE *ThisInstance;\r |
7e7b729f AC |
117 | \r |
118 | if (IsListEmpty (&mRedfishDiscoverList)) {\r | |
119 | return NULL;\r | |
120 | }\r | |
39de741e | 121 | \r |
7e7b729f AC |
122 | ThisInstance =\r |
123 | (EFI_REDFISH_DISCOVERED_INTERNAL_INSTANCE *)GetFirstNode (&mRedfishDiscoverList);\r | |
124 | while (TRUE) {\r | |
125 | if ((ThisInstance->Owner == ImageHandle) &&\r | |
39de741e MK |
126 | (ThisInstance->DiscoverFlags == DiscoverFlags) &&\r |
127 | (ThisInstance->NetworkInterface == TargetNetworkInterface))\r | |
128 | {\r | |
7e7b729f AC |
129 | return ThisInstance;\r |
130 | }\r | |
39de741e | 131 | \r |
7e7b729f AC |
132 | if (IsNodeAtEnd (&mRedfishDiscoverList, &ThisInstance->Entry)) {\r |
133 | break;\r | |
134 | }\r | |
39de741e | 135 | \r |
7e7b729f AC |
136 | ThisInstance =\r |
137 | (EFI_REDFISH_DISCOVERED_INTERNAL_INSTANCE *)GetNextNode (&mRedfishDiscoverList, &ThisInstance->Entry);\r | |
39de741e MK |
138 | }\r |
139 | \r | |
7e7b729f AC |
140 | return NULL;\r |
141 | }\r | |
142 | \r | |
143 | /**\r | |
144 | This function gets the subnet information of this TCP4 instance.\r | |
145 | \r | |
146 | @param[in] ImageHandle EFI handle with this image.\r | |
147 | @param[in] Instance Instance of Network interface.\r | |
148 | @retval EFI_STATUS Get subnet information successfully.\r | |
149 | @retval Otherwise Fail to get subnet information.\r | |
150 | **/\r | |
151 | EFI_STATUS\r | |
152 | EFIAPI\r | |
153 | Tcp4GetSubnetInfo (\r | |
39de741e MK |
154 | IN EFI_HANDLE ImageHandle,\r |
155 | IN EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *Instance\r | |
156 | )\r | |
7e7b729f | 157 | {\r |
39de741e MK |
158 | EFI_STATUS Status;\r |
159 | EFI_TCP4_PROTOCOL *Tcp4;\r | |
160 | EFI_TCP4_CONFIG_DATA Tcp4CfgData;\r | |
161 | EFI_TCP4_OPTION Tcp4Option;\r | |
162 | EFI_IP4_MODE_DATA IpModedata;\r | |
163 | UINT8 SubnetMaskIndex;\r | |
164 | UINT8 BitMask;\r | |
165 | UINT8 PrefixLength;\r | |
166 | BOOLEAN GotPrefixLength;\r | |
7e7b729f AC |
167 | \r |
168 | if (Instance == NULL) {\r | |
169 | return EFI_INVALID_PARAMETER;\r | |
170 | }\r | |
39de741e | 171 | \r |
7e7b729f AC |
172 | Tcp4 = (EFI_TCP4_PROTOCOL *)Instance->NetworkInterfaceProtocolInfo.NetworkProtocolInterface;\r |
173 | \r | |
174 | ZeroMem ((VOID *)&Tcp4CfgData, sizeof (EFI_TCP4_CONFIG_DATA));\r | |
175 | ZeroMem ((VOID *)&Tcp4Option, sizeof (EFI_TCP4_OPTION));\r | |
176 | // Give a local host IP address just for getting subnet information.\r | |
39de741e MK |
177 | Tcp4CfgData.AccessPoint.UseDefaultAddress = TRUE;\r |
178 | Tcp4CfgData.AccessPoint.RemoteAddress.Addr[0] = 127;\r | |
179 | Tcp4CfgData.AccessPoint.RemoteAddress.Addr[1] = 0;\r | |
180 | Tcp4CfgData.AccessPoint.RemoteAddress.Addr[2] = 0;\r | |
181 | Tcp4CfgData.AccessPoint.RemoteAddress.Addr[3] = 1;\r | |
182 | Tcp4CfgData.AccessPoint.RemotePort = 80;\r | |
183 | Tcp4CfgData.AccessPoint.ActiveFlag = TRUE;\r | |
184 | \r | |
185 | Tcp4CfgData.ControlOption = &Tcp4Option;\r | |
186 | Tcp4Option.ReceiveBufferSize = 65535;\r | |
187 | Tcp4Option.SendBufferSize = 65535;\r | |
188 | Tcp4Option.MaxSynBackLog = 5;\r | |
189 | Tcp4Option.ConnectionTimeout = 60;\r | |
190 | Tcp4Option.DataRetries = 12;\r | |
191 | Tcp4Option.FinTimeout = 2;\r | |
192 | Tcp4Option.KeepAliveProbes = 6;\r | |
193 | Tcp4Option.KeepAliveTime = 7200;\r | |
194 | Tcp4Option.KeepAliveInterval = 30;\r | |
195 | Tcp4Option.EnableNagle = TRUE;\r | |
196 | Status = Tcp4->Configure (Tcp4, &Tcp4CfgData);\r | |
7e7b729f AC |
197 | if (EFI_ERROR (Status)) {\r |
198 | DEBUG ((DEBUG_ERROR, "%a: Can't get subnet information\n", __FUNCTION__));\r | |
199 | return Status;\r | |
200 | }\r | |
39de741e | 201 | \r |
7e7b729f AC |
202 | Status = Tcp4->GetModeData (Tcp4, NULL, NULL, &IpModedata, NULL, NULL);\r |
203 | if (EFI_ERROR (Status)) {\r | |
204 | DEBUG ((DEBUG_ERROR, "%a: Can't get IP mode data information\n", __FUNCTION__));\r | |
205 | return Status;\r | |
206 | }\r | |
39de741e | 207 | \r |
7e7b729f | 208 | IP4_COPY_ADDRESS (&Instance->SubnetMask, &IpModedata.ConfigData.SubnetMask);\r |
39de741e MK |
209 | Instance->SubnetAddr.v4.Addr[0] = IpModedata.ConfigData.StationAddress.Addr[0] & Instance->SubnetMask.v4.Addr[0];\r |
210 | Instance->SubnetAddr.v4.Addr[1] = IpModedata.ConfigData.StationAddress.Addr[1] & Instance->SubnetMask.v4.Addr[1];\r | |
211 | Instance->SubnetAddr.v4.Addr[2] = IpModedata.ConfigData.StationAddress.Addr[2] & Instance->SubnetMask.v4.Addr[2];\r | |
212 | Instance->SubnetAddr.v4.Addr[3] = IpModedata.ConfigData.StationAddress.Addr[3] & Instance->SubnetMask.v4.Addr[3];\r | |
7e7b729f AC |
213 | //\r |
214 | // Calculate the subnet mask prefix.\r | |
215 | //\r | |
216 | GotPrefixLength = FALSE;\r | |
39de741e | 217 | PrefixLength = 0;\r |
7e7b729f AC |
218 | SubnetMaskIndex = 0;\r |
219 | while (GotPrefixLength == FALSE && SubnetMaskIndex < 4) {\r | |
220 | BitMask = 0x80;\r | |
221 | while (BitMask != 0) {\r | |
39de741e MK |
222 | if ((Instance->SubnetMask.v4.Addr[SubnetMaskIndex] & BitMask) != 0) {\r |
223 | PrefixLength++;\r | |
7e7b729f AC |
224 | } else {\r |
225 | GotPrefixLength = TRUE;\r | |
226 | break;\r | |
227 | }\r | |
39de741e | 228 | \r |
7e7b729f | 229 | BitMask = BitMask >> 1;\r |
39de741e MK |
230 | }\r |
231 | \r | |
232 | SubnetMaskIndex++;\r | |
233 | }\r | |
234 | \r | |
7e7b729f AC |
235 | Instance->SubnetPrefixLength = PrefixLength;\r |
236 | return EFI_SUCCESS;\r | |
237 | }\r | |
238 | \r | |
239 | /**\r | |
240 | This function gets the subnet information of this TCP6 instance.\r | |
241 | \r | |
242 | @param[in] ImageHandle EFI handle with this image.\r | |
243 | @param[in] Instance Instance of Network interface.\r | |
244 | @retval EFI_STATUS Get subnet information successfully.\r | |
245 | @retval Otherwise Fail to get subnet information.\r | |
246 | **/\r | |
247 | EFI_STATUS\r | |
248 | EFIAPI\r | |
249 | Tcp6GetSubnetInfo (\r | |
39de741e MK |
250 | IN EFI_HANDLE ImageHandle,\r |
251 | IN EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *Instance\r | |
252 | )\r | |
7e7b729f | 253 | {\r |
39de741e MK |
254 | EFI_STATUS Status;\r |
255 | EFI_TCP6_PROTOCOL *Tcp6;\r | |
256 | EFI_IP6_MODE_DATA IpModedata;\r | |
7e7b729f AC |
257 | \r |
258 | if (Instance == NULL) {\r | |
259 | return EFI_INVALID_PARAMETER;\r | |
260 | }\r | |
39de741e | 261 | \r |
7e7b729f AC |
262 | Tcp6 = (EFI_TCP6_PROTOCOL *)Instance->NetworkInterfaceProtocolInfo.NetworkProtocolInterface;\r |
263 | \r | |
264 | Status = Tcp6->GetModeData (Tcp6, NULL, NULL, &IpModedata, NULL, NULL);\r | |
265 | if (EFI_ERROR (Status)) {\r | |
266 | DEBUG ((DEBUG_ERROR, "%a: Can't get IP mode data information\n"));\r | |
267 | return Status;\r | |
268 | }\r | |
39de741e | 269 | \r |
7e7b729f AC |
270 | if (IpModedata.AddressCount == 0) {\r |
271 | DEBUG ((DEBUG_INFO, "%a: No IPv6 address configured.\n"));\r | |
272 | }\r | |
39de741e | 273 | \r |
7e7b729f AC |
274 | if (Instance->SubnetAddrInfoIPv6 != NULL) {\r |
275 | FreePool (Instance->SubnetAddrInfoIPv6);\r | |
276 | }\r | |
39de741e | 277 | \r |
7e7b729f AC |
278 | Instance->SubnetAddrInfoIPv6 = AllocateZeroPool (IpModedata.AddressCount * sizeof (EFI_IP6_ADDRESS_INFO));\r |
279 | if (Instance->SubnetAddrInfoIPv6 == NULL) {\r | |
280 | DEBUG ((DEBUG_ERROR, "%a: Failed to allocate memory fir IPv6 subnet address information\n"));\r | |
281 | return EFI_OUT_OF_RESOURCES;\r | |
282 | }\r | |
39de741e | 283 | \r |
7e7b729f AC |
284 | Instance->SubnetAddrInfoIPv6Number = IpModedata.AddressCount;\r |
285 | CopyMem (\r | |
286 | (VOID *)Instance->SubnetAddrInfoIPv6,\r | |
287 | (VOID *)&IpModedata.AddressList,\r | |
288 | IpModedata.AddressCount * sizeof (EFI_IP6_ADDRESS_INFO)\r | |
289 | );\r | |
290 | FreePool (IpModedata.AddressList);\r | |
291 | return EFI_SUCCESS;\r | |
292 | }\r | |
293 | \r | |
294 | /**\r | |
295 | This function searches EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL\r | |
296 | instance with the given EFI_REDFISH_DISCOVER_NETWORK_INTERFACE.\r | |
297 | \r | |
298 | @param[in] TargetNetworkInterface EFI_REDFISH_DISCOVER_NETWORK_INTERFACE.\r | |
299 | NULL for all EFI_REDFISH_DISCOVER_NETWORK_INTERFACEs.\r | |
300 | \r | |
301 | @retval Non-NULL EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL is returned.\r | |
302 | @retval NULL Non of EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL instance is returned.\r | |
303 | **/\r | |
304 | EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *\r | |
305 | GetTargetNetworkInterfaceInternal (\r | |
306 | IN EFI_REDFISH_DISCOVER_NETWORK_INTERFACE *TargetNetworkInterface\r | |
307 | )\r | |
308 | {\r | |
39de741e | 309 | EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *ThisNetworkInterface;\r |
7e7b729f AC |
310 | \r |
311 | ThisNetworkInterface = (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *)GetFirstNode (&mEfiRedfishDiscoverNetworkInterface);\r | |
312 | while (TRUE) {\r | |
39de741e | 313 | if (CompareMem ((VOID *)&ThisNetworkInterface->MacAddress, &TargetNetworkInterface->MacAddress, ThisNetworkInterface->HwAddressSize) == 0) {\r |
7e7b729f AC |
314 | return ThisNetworkInterface;\r |
315 | }\r | |
39de741e | 316 | \r |
7e7b729f AC |
317 | if (IsNodeAtEnd (&mEfiRedfishDiscoverNetworkInterface, &ThisNetworkInterface->Entry)) {\r |
318 | return NULL;\r | |
319 | }\r | |
39de741e MK |
320 | \r |
321 | ThisNetworkInterface = (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *)GetNextNode (&mEfiRedfishDiscoverNetworkInterface, &ThisNetworkInterface->Entry);\r | |
322 | }\r | |
323 | \r | |
7e7b729f AC |
324 | return NULL;\r |
325 | }\r | |
326 | \r | |
f7da805b AC |
327 | /**\r |
328 | This function searches EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL\r | |
329 | instance with the given Controller handle.\r | |
330 | \r | |
331 | @param[in] ControllerHandle The controller handle associated with network interface.\r | |
332 | \r | |
333 | @retval Non-NULL EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL is returned.\r | |
334 | @retval NULL Non of EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL instance is returned.\r | |
335 | **/\r | |
336 | EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *\r | |
337 | GetTargetNetworkInterfaceInternalByController (\r | |
338 | IN EFI_HANDLE ControllerHandle\r | |
339 | )\r | |
340 | {\r | |
341 | EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *ThisNetworkInterface;\r | |
342 | \r | |
343 | ThisNetworkInterface = (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *)GetFirstNode (&mEfiRedfishDiscoverNetworkInterface);\r | |
344 | while (TRUE) {\r | |
345 | if (ThisNetworkInterface->OpenDriverControllerHandle == ControllerHandle) {\r | |
346 | return ThisNetworkInterface;\r | |
347 | }\r | |
348 | \r | |
349 | if (IsNodeAtEnd (&mEfiRedfishDiscoverNetworkInterface, &ThisNetworkInterface->Entry)) {\r | |
350 | return NULL;\r | |
351 | }\r | |
352 | \r | |
353 | ThisNetworkInterface = (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *)GetNextNode (&mEfiRedfishDiscoverNetworkInterface, &ThisNetworkInterface->Entry);\r | |
354 | }\r | |
355 | \r | |
356 | return NULL;\r | |
357 | }\r | |
358 | \r | |
7e7b729f AC |
359 | /**\r |
360 | This function validate if target network interface is ready for discovering\r | |
361 | Redfish service.\r | |
362 | \r | |
363 | @param[in] TargetNetworkInterface EFI_REDFISH_DISCOVER_NETWORK_INTERFACE.\r | |
364 | NULL for all EFI_REDFISH_DISCOVER_NETWORK_INTERFACEs.\r | |
365 | @param[in] Flags EFI_REDFISH_DISCOVER_FLAG\r | |
366 | \r | |
367 | @retval EFI_SUCCESS Target network interface is ready to use.\r | |
368 | @retval EFI_UNSUPPORTED Target network interface is not ready to use.\r | |
369 | **/\r | |
370 | EFI_STATUS\r | |
371 | ValidateTargetNetworkInterface (\r | |
372 | IN EFI_REDFISH_DISCOVER_NETWORK_INTERFACE *TargetNetworkInterface,\r | |
39de741e | 373 | IN EFI_REDFISH_DISCOVER_FLAG Flags\r |
7e7b729f AC |
374 | )\r |
375 | {\r | |
39de741e | 376 | EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *ThisNetworkInterface;\r |
7e7b729f | 377 | \r |
39de741e | 378 | if (IsListEmpty (&mEfiRedfishDiscoverNetworkInterface) && (TargetNetworkInterface == NULL)) {\r |
7e7b729f AC |
379 | return EFI_UNSUPPORTED;\r |
380 | }\r | |
39de741e | 381 | \r |
7e7b729f AC |
382 | if (TargetNetworkInterface == NULL) {\r |
383 | return EFI_SUCCESS; // Return EFI_SUCCESS if no network interface is specified.\r | |
384 | }\r | |
385 | \r | |
39de741e | 386 | ThisNetworkInterface = (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *)GetFirstNode (&mEfiRedfishDiscoverNetworkInterface);\r |
7e7b729f | 387 | while (TRUE) {\r |
39de741e | 388 | if (CompareMem ((VOID *)&ThisNetworkInterface->MacAddress, &TargetNetworkInterface->MacAddress, ThisNetworkInterface->HwAddressSize) == 0) {\r |
7e7b729f AC |
389 | break;\r |
390 | }\r | |
39de741e | 391 | \r |
7e7b729f AC |
392 | if (IsNodeAtEnd (&mEfiRedfishDiscoverNetworkInterface, &ThisNetworkInterface->Entry)) {\r |
393 | return EFI_UNSUPPORTED;\r | |
394 | }\r | |
39de741e MK |
395 | \r |
396 | ThisNetworkInterface = (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *)GetNextNode (&mEfiRedfishDiscoverNetworkInterface, &ThisNetworkInterface->Entry);\r | |
397 | }\r | |
398 | \r | |
7e7b729f AC |
399 | if ((Flags & EFI_REDFISH_DISCOVER_SSDP) != 0) {\r |
400 | // Validate if UDP4/6 is supported on the given network interface.\r | |
401 | // SSDP is not supported.\r | |
402 | \r | |
403 | return EFI_SUCCESS;\r | |
404 | }\r | |
39de741e | 405 | \r |
7e7b729f AC |
406 | if (ThisNetworkInterface->NetworkInterfaceProtocolInfo.ProtocolControllerHandle == NULL) {\r |
407 | return EFI_UNSUPPORTED; // The required protocol on this network interface is not found.\r | |
408 | }\r | |
39de741e | 409 | \r |
7e7b729f AC |
410 | return EFI_SUCCESS;\r |
411 | }\r | |
39de741e | 412 | \r |
7e7b729f AC |
413 | /**\r |
414 | This function returns number of network interface instance.\r | |
415 | \r | |
416 | @retval UINTN Number of network interface instances.\r | |
417 | **/\r | |
418 | UINTN\r | |
39de741e MK |
419 | NumberOfNetworkInterface (\r |
420 | VOID\r | |
421 | )\r | |
7e7b729f | 422 | {\r |
39de741e MK |
423 | UINTN Num;\r |
424 | EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *ThisNetworkInterface;\r | |
7e7b729f AC |
425 | \r |
426 | if (IsListEmpty (&mEfiRedfishDiscoverNetworkInterface)) {\r | |
427 | return 0;\r | |
428 | }\r | |
429 | \r | |
39de741e | 430 | Num = 1;\r |
7e7b729f AC |
431 | ThisNetworkInterface = (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *)GetFirstNode (&mEfiRedfishDiscoverNetworkInterface);\r |
432 | while (TRUE) {\r | |
433 | if (IsNodeAtEnd (&mEfiRedfishDiscoverNetworkInterface, &ThisNetworkInterface->Entry)) {\r | |
434 | break;\r | |
435 | }\r | |
39de741e MK |
436 | \r |
437 | ThisNetworkInterface = (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *)GetNextNode (&mEfiRedfishDiscoverNetworkInterface, &ThisNetworkInterface->Entry);\r | |
438 | Num++;\r | |
439 | }\r | |
440 | \r | |
7e7b729f AC |
441 | return Num;\r |
442 | }\r | |
443 | \r | |
444 | /**\r | |
445 | This function checks the IP version supported on this\r | |
446 | netwoek interface.\r | |
447 | \r | |
448 | @param[in] ThisNetworkInterface EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL\r | |
449 | \r | |
450 | @retval TRUE Is IPv6, otherwise IPv4.\r | |
451 | \r | |
452 | **/\r | |
453 | BOOLEAN\r | |
454 | CheckIsIpVersion6 (\r | |
39de741e MK |
455 | IN EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *ThisNetworkInterface\r |
456 | )\r | |
7e7b729f AC |
457 | {\r |
458 | if (ThisNetworkInterface->NetworkProtocolType == ProtocolTypeTcp6) {\r | |
459 | return TRUE;\r | |
460 | }\r | |
39de741e | 461 | \r |
7e7b729f AC |
462 | return FALSE;\r |
463 | }\r | |
464 | \r | |
465 | /**\r | |
466 | This function discover Redfish service through SMBIOS host interface.\r | |
467 | \r | |
468 | @param[in] Instance EFI_REDFISH_DISCOVERED_INTERNAL_INSTANCE\r | |
469 | \r | |
470 | @retval EFI_SUCCESS Redfish service is discovered through SMBIOS Host interface.\r | |
471 | @retval Others Fail to discover Redfish service throught SMBIOS host interface\r | |
472 | \r | |
473 | **/\r | |
474 | EFI_STATUS\r | |
39de741e MK |
475 | DiscoverRedfishHostInterface (\r |
476 | IN EFI_REDFISH_DISCOVERED_INTERNAL_INSTANCE *Instance\r | |
477 | )\r | |
7e7b729f | 478 | {\r |
39de741e MK |
479 | EFI_STATUS Status;\r |
480 | REDFISH_OVER_IP_PROTOCOL_DATA *Data;\r | |
481 | REDFISH_INTERFACE_DATA *DeviceDescriptor;\r | |
482 | CHAR8 UuidStr[sizeof "00000000-0000-0000-0000-000000000000" + 1];\r | |
483 | CHAR16 Ipv6Str[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff" + 1];\r | |
484 | CHAR8 RedfishServiceLocateStr[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff" + 1];\r | |
485 | UINTN StrSize;\r | |
486 | UINTN MacCompareStstus;\r | |
487 | BOOLEAN IsHttps;\r | |
488 | \r | |
489 | Data = NULL;\r | |
7e7b729f AC |
490 | DeviceDescriptor = NULL;\r |
491 | \r | |
492 | if (mSmbios == NULL) {\r | |
39de741e | 493 | Status = gBS->LocateProtocol (&gEfiSmbiosProtocolGuid, NULL, (VOID **)&mSmbios);\r |
7e7b729f AC |
494 | if (EFI_ERROR (Status)) {\r |
495 | return Status;\r | |
496 | }\r | |
497 | }\r | |
39de741e | 498 | \r |
7e7b729f | 499 | Status = RedfishGetHostInterfaceProtocolData (mSmbios, &DeviceDescriptor, &Data); // Search for SMBIOS type 42h\r |
39de741e | 500 | if (!EFI_ERROR (Status) && (Data != NULL) && (DeviceDescriptor != NULL)) {\r |
7e7b729f AC |
501 | //\r |
502 | // Chceck if we can reach out Redfish service using this network interface.\r | |
503 | // Check with MAC address using Device Descroptor Data Device Type 04 and Type 05.\r | |
504 | // Those two types of Redfish host interface device has MAC information.\r | |
505 | //\r | |
506 | if (DeviceDescriptor->DeviceType == REDFISH_HOST_INTERFACE_DEVICE_TYPE_PCI_PCIE_V2) {\r | |
39de741e MK |
507 | MacCompareStstus = CompareMem (&Instance->NetworkInterface->MacAddress, &DeviceDescriptor->DeviceDescriptor.PciPcieDeviceV2.MacAddress, 6);\r |
508 | } else if (DeviceDescriptor->DeviceType == REDFISH_HOST_INTERFACE_DEVICE_TYPE_USB_V2) {\r | |
509 | MacCompareStstus = CompareMem (&Instance->NetworkInterface->MacAddress, &DeviceDescriptor->DeviceDescriptor.UsbDeviceV2.MacAddress, 6);\r | |
7e7b729f AC |
510 | } else {\r |
511 | return EFI_UNSUPPORTED;\r | |
512 | }\r | |
39de741e | 513 | \r |
7e7b729f AC |
514 | if (MacCompareStstus != 0) {\r |
515 | return EFI_UNSUPPORTED;\r | |
516 | }\r | |
517 | \r | |
518 | if (Data->RedfishServiceIpAddressFormat == 1) {\r | |
519 | IP4_COPY_ADDRESS ((VOID *)&Instance->TargetIpAddress.v4, (VOID *)Data->RedfishServiceIpAddress);\r | |
520 | } else {\r | |
521 | IP6_COPY_ADDRESS ((VOID *)&Instance->TargetIpAddress.v6, (VOID *)Data->RedfishServiceIpAddress);\r | |
522 | }\r | |
523 | \r | |
524 | if (Instance->HostIntfValidation) {\r | |
39de741e | 525 | DEBUG ((DEBUG_ERROR, "%a:Send UPnP unicast SSDP to validate this Redfish Host Interface is not supported.\n", __FUNCTION__));\r |
7e7b729f AC |
526 | Status = EFI_UNSUPPORTED;\r |
527 | } else {\r | |
528 | //\r | |
529 | // Add this istance to list without detial information of Redfish\r | |
530 | // service.\r | |
531 | //\r | |
532 | IsHttps = FALSE;\r | |
533 | if (Data->RedfishServiceIpPort == 443) {\r | |
534 | IsHttps = TRUE;\r | |
535 | }\r | |
39de741e MK |
536 | \r |
537 | StrSize = sizeof (UuidStr);\r | |
538 | AsciiSPrint (UuidStr, StrSize, "%g", &Data->ServiceUuid);\r | |
7e7b729f AC |
539 | //\r |
540 | // Generate Redfish service location string.\r | |
541 | //\r | |
542 | if (Data->RedfishServiceIpAddressFormat == REDFISH_HOST_INTERFACE_HOST_IP_ADDRESS_FORMAT_IP6) {\r | |
39de741e MK |
543 | NetLibIp6ToStr ((IPv6_ADDRESS *)&Data->RedfishServiceIpAddress, Ipv6Str, sizeof (Ipv6Str));\r |
544 | if ((Data->RedfishServiceIpPort == 0) || (IsHttps == TRUE)) {\r | |
545 | AsciiSPrintUnicodeFormat (\r | |
546 | RedfishServiceLocateStr,\r | |
547 | sizeof (RedfishServiceLocateStr),\r | |
548 | L"%s",\r | |
549 | Ipv6Str\r | |
7e7b729f AC |
550 | );\r |
551 | } else {\r | |
39de741e MK |
552 | AsciiSPrintUnicodeFormat (\r |
553 | RedfishServiceLocateStr,\r | |
554 | sizeof (RedfishServiceLocateStr),\r | |
555 | L"[%s]:%d",\r | |
556 | Ipv6Str,\r | |
557 | Data->RedfishServiceIpPort\r | |
7e7b729f AC |
558 | );\r |
559 | }\r | |
560 | } else {\r | |
39de741e MK |
561 | if ((Data->RedfishServiceIpPort == 0) || (IsHttps == TRUE)) {\r |
562 | AsciiSPrint (\r | |
7e7b729f AC |
563 | RedfishServiceLocateStr,\r |
564 | sizeof (RedfishServiceLocateStr),\r | |
565 | "%d.%d.%d.%d",\r | |
39de741e MK |
566 | Data->RedfishServiceIpAddress[0],\r |
567 | Data->RedfishServiceIpAddress[1],\r | |
568 | Data->RedfishServiceIpAddress[2],\r | |
569 | Data->RedfishServiceIpAddress[3]\r | |
7e7b729f AC |
570 | );\r |
571 | } else {\r | |
39de741e | 572 | AsciiSPrint (\r |
7e7b729f AC |
573 | RedfishServiceLocateStr,\r |
574 | sizeof (RedfishServiceLocateStr),\r | |
575 | "%d.%d.%d.%d:%d",\r | |
39de741e MK |
576 | Data->RedfishServiceIpAddress[0],\r |
577 | Data->RedfishServiceIpAddress[1],\r | |
578 | Data->RedfishServiceIpAddress[2],\r | |
579 | Data->RedfishServiceIpAddress[3],\r | |
7e7b729f AC |
580 | Data->RedfishServiceIpPort\r |
581 | );\r | |
582 | }\r | |
39de741e MK |
583 | }\r |
584 | \r | |
7e7b729f | 585 | Status = AddAndSignalNewRedfishService (\r |
39de741e MK |
586 | Instance,\r |
587 | NULL,\r | |
588 | RedfishServiceLocateStr,\r | |
589 | UuidStr,\r | |
590 | NULL,\r | |
591 | NULL,\r | |
592 | NULL,\r | |
593 | NULL,\r | |
594 | IsHttps\r | |
595 | );\r | |
7e7b729f AC |
596 | }\r |
597 | }\r | |
39de741e | 598 | \r |
7e7b729f AC |
599 | return Status;\r |
600 | }\r | |
601 | \r | |
602 | /**\r | |
603 | The function adds a new found Redfish service to internal list and\r | |
604 | notify client.\r | |
605 | \r | |
606 | @param[in] Instance EFI_REDFISH_DISCOVERED_INTERNAL_INSTANCE.\r | |
607 | @param[in] RedfishVersion Redfish version.\r | |
608 | @param[in] RedfishLocation Redfish location.\r | |
609 | @param[in] Uuid Service UUID string.\r | |
610 | @param[in] Os OS string.\r | |
611 | @param[in] OsVer OS version string.\r | |
612 | @param[in] Product Product string.\r | |
613 | @param[in] ProductVer Product verison string.\r | |
614 | @param[in] UseHttps Redfish service requires secured connection.\r | |
615 | @retval EFI_SUCCESS Redfish service is added to list successfully.\r | |
616 | \r | |
617 | **/\r | |
618 | EFI_STATUS\r | |
619 | AddAndSignalNewRedfishService (\r | |
39de741e MK |
620 | IN EFI_REDFISH_DISCOVERED_INTERNAL_INSTANCE *Instance,\r |
621 | IN UINTN *RedfishVersion OPTIONAL,\r | |
622 | IN CHAR8 *RedfishLocation OPTIONAL,\r | |
623 | IN CHAR8 *Uuid OPTIONAL,\r | |
624 | IN CHAR8 *Os OPTIONAL,\r | |
625 | IN CHAR8 *OsVer OPTIONAL,\r | |
626 | IN CHAR8 *Product OPTIONAL,\r | |
627 | IN CHAR8 *ProductVer OPTIONAL,\r | |
628 | IN BOOLEAN UseHttps\r | |
7e7b729f AC |
629 | )\r |
630 | {\r | |
39de741e MK |
631 | BOOLEAN NewFound;\r |
632 | BOOLEAN InfoRefresh;\r | |
633 | BOOLEAN RestExOpened;\r | |
634 | BOOLEAN DeleteRestEx;\r | |
635 | EFI_STATUS Status;\r | |
636 | EFI_REDFISH_DISCOVERED_INTERNAL_LIST *DiscoveredList;\r | |
637 | EFI_REDFISH_DISCOVERED_INSTANCE *DiscoveredInstance;\r | |
638 | CHAR16 *Char16Uuid;\r | |
639 | EFI_REST_EX_PROTOCOL *RestEx;\r | |
640 | EFI_REST_EX_HTTP_CONFIG_DATA *RestExHttpConfigData;\r | |
641 | EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *NetworkInterface;\r | |
642 | \r | |
643 | NewFound = TRUE;\r | |
644 | InfoRefresh = FALSE;\r | |
645 | Char16Uuid = NULL;\r | |
7e7b729f AC |
646 | RestExOpened = FALSE;\r |
647 | DeleteRestEx = FALSE;\r | |
648 | \r | |
39de741e | 649 | DEBUG ((DEBUG_INFO, "%a:Add this instance to Redfish instance list.\n", __FUNCTION__));\r |
7e7b729f AC |
650 | \r |
651 | if (Uuid != NULL) {\r | |
39de741e MK |
652 | Char16Uuid = (CHAR16 *)AllocateZeroPool (AsciiStrSize ((const CHAR8 *)Uuid) * sizeof (CHAR16));\r |
653 | AsciiStrToUnicodeStrS ((const CHAR8 *)Uuid, Char16Uuid, AsciiStrSize ((const CHAR8 *)Uuid) * sizeof (CHAR16));\r | |
7e7b729f | 654 | }\r |
39de741e MK |
655 | \r |
656 | DiscoveredList = NULL;\r | |
657 | DiscoveredInstance = NULL;\r | |
7e7b729f AC |
658 | RestExHttpConfigData = NULL;\r |
659 | \r | |
660 | NetworkInterface = Instance->NetworkInterface;\r | |
661 | if (!IsListEmpty (&mRedfishInstanceList)) {\r | |
662 | //\r | |
663 | // Is this a duplicate redfish service.\r | |
664 | //\r | |
665 | DiscoveredList = (EFI_REDFISH_DISCOVERED_INTERNAL_LIST *)GetFirstNode (&mRedfishInstanceList);\r | |
39de741e | 666 | NewFound = FALSE;\r |
7e7b729f | 667 | do {\r |
39de741e | 668 | if ((Char16Uuid == NULL) || (DiscoveredList->Instance->Information.Uuid == NULL)) {\r |
7e7b729f AC |
669 | //\r |
670 | // Check if this Redfish instance already found using IP addrress.\r | |
671 | //\r | |
39de741e MK |
672 | if (!CheckIsIpVersion6 (NetworkInterface)) {\r |
673 | if (CompareMem (\r | |
674 | (VOID *)&Instance->TargetIpAddress.v4,\r | |
675 | (VOID *)&DiscoveredList->Instance->Information.RedfishHostIpAddress.v4,\r | |
676 | sizeof (EFI_IPv4_ADDRESS)\r | |
677 | ) == 0)\r | |
7e7b729f AC |
678 | {\r |
679 | DiscoveredInstance = DiscoveredList->Instance;\r | |
39de741e MK |
680 | if ((DiscoveredList->Instance->Information.Uuid == NULL) &&\r |
681 | (Char16Uuid != NULL))\r | |
682 | {\r | |
683 | InfoRefresh = TRUE;\r | |
7e7b729f | 684 | DiscoveredInstance = DiscoveredList->Instance;\r |
39de741e | 685 | DEBUG ((DEBUG_INFO, "*** This Redfish Service information refresh ***\n"));\r |
7e7b729f | 686 | }\r |
39de741e | 687 | \r |
7e7b729f AC |
688 | break;\r |
689 | }\r | |
690 | } else {\r | |
39de741e MK |
691 | if (CompareMem (\r |
692 | (VOID *)&Instance->TargetIpAddress.v6,\r | |
693 | (VOID *)&DiscoveredList->Instance->Information.RedfishHostIpAddress.v6,\r | |
694 | sizeof (EFI_IPv6_ADDRESS)\r | |
695 | ) == 0)\r | |
7e7b729f AC |
696 | {\r |
697 | DiscoveredInstance = DiscoveredList->Instance;\r | |
698 | break;\r | |
699 | }\r | |
700 | }\r | |
701 | } else {\r | |
702 | //\r | |
703 | // Check if this Redfish instance already found using UUID.\r | |
704 | //\r | |
39de741e | 705 | if (StrCmp ((const CHAR16 *)Char16Uuid, (const CHAR16 *)DiscoveredList->Instance->Information.Uuid) == 0) {\r |
7e7b729f AC |
706 | DiscoveredInstance = DiscoveredList->Instance;\r |
707 | break;\r | |
708 | }\r | |
709 | }\r | |
39de741e | 710 | \r |
7e7b729f AC |
711 | if (IsNodeAtEnd (&mRedfishInstanceList, &DiscoveredList->NextInstance)) {\r |
712 | NewFound = TRUE;\r | |
713 | break;\r | |
714 | }\r | |
39de741e | 715 | \r |
7e7b729f AC |
716 | DiscoveredList = (EFI_REDFISH_DISCOVERED_INTERNAL_LIST *)GetNextNode (&mRedfishInstanceList, &DiscoveredList->NextInstance);\r |
717 | } while (TRUE);\r | |
718 | }\r | |
39de741e | 719 | \r |
7e7b729f AC |
720 | if (NewFound || InfoRefresh) {\r |
721 | if (!InfoRefresh) {\r | |
39de741e | 722 | DiscoveredList = (EFI_REDFISH_DISCOVERED_INTERNAL_LIST *)AllocateZeroPool (sizeof (EFI_REDFISH_DISCOVERED_INTERNAL_LIST));\r |
7e7b729f AC |
723 | if (DiscoveredList == NULL) {\r |
724 | return EFI_OUT_OF_RESOURCES;\r | |
725 | }\r | |
39de741e | 726 | \r |
7e7b729f | 727 | InitializeListHead (&DiscoveredList->NextInstance);\r |
39de741e | 728 | DiscoveredInstance = (EFI_REDFISH_DISCOVERED_INSTANCE *)AllocateZeroPool (sizeof (EFI_REDFISH_DISCOVERED_INSTANCE));\r |
7e7b729f AC |
729 | if (DiscoveredInstance == NULL) {\r |
730 | FreePool ((VOID *)DiscoveredList);\r | |
731 | return EFI_OUT_OF_RESOURCES;\r | |
732 | }\r | |
733 | }\r | |
39de741e MK |
734 | \r |
735 | DEBUG ((DEBUG_INFO, "*** Redfish Service Information ***\n"));\r | |
7e7b729f AC |
736 | \r |
737 | DiscoveredInstance->Information.UseHttps = UseHttps;\r | |
738 | if (RedfishVersion != NULL) {\r | |
739 | DiscoveredInstance->Information.RedfishVersion = *RedfishVersion;\r | |
39de741e | 740 | DEBUG ((DEBUG_INFO, "Redfish service version: %d.\n", DiscoveredInstance->Information.RedfishVersion));\r |
7e7b729f | 741 | }\r |
39de741e | 742 | \r |
7e7b729f | 743 | if (RedfishLocation != NULL) {\r |
39de741e MK |
744 | DiscoveredInstance->Information.Location = (CHAR16 *)AllocatePool (AsciiStrSize ((const CHAR8 *)RedfishLocation) * sizeof (CHAR16));\r |
745 | AsciiStrToUnicodeStrS ((const CHAR8 *)RedfishLocation, DiscoveredInstance->Information.Location, AsciiStrSize ((const CHAR8 *)RedfishLocation) * sizeof (CHAR16));\r | |
746 | DEBUG ((DEBUG_INFO, "Redfish service location: %s.\n", DiscoveredInstance->Information.Location));\r | |
7e7b729f | 747 | }\r |
39de741e | 748 | \r |
7e7b729f | 749 | if (Uuid != NULL) {\r |
39de741e MK |
750 | DiscoveredInstance->Information.Uuid = (CHAR16 *)AllocatePool (AsciiStrSize ((const CHAR8 *)Uuid) * sizeof (CHAR16));\r |
751 | AsciiStrToUnicodeStrS ((const CHAR8 *)Uuid, DiscoveredInstance->Information.Uuid, AsciiStrSize ((const CHAR8 *)Uuid) * sizeof (CHAR16));\r | |
752 | DEBUG ((DEBUG_INFO, "Service UUID: %s.\n", DiscoveredInstance->Information.Uuid));\r | |
7e7b729f | 753 | }\r |
39de741e | 754 | \r |
7e7b729f | 755 | if (Os != NULL) {\r |
39de741e MK |
756 | DiscoveredInstance->Information.Os = (CHAR16 *)AllocatePool (AsciiStrSize ((const CHAR8 *)Os) * sizeof (CHAR16));\r |
757 | AsciiStrToUnicodeStrS ((const CHAR8 *)Os, DiscoveredInstance->Information.Os, AsciiStrSize ((const CHAR8 *)Os) * sizeof (CHAR16));\r | |
758 | DEBUG ((DEBUG_INFO, "Redfish service OS: %s, Version:%s.\n", DiscoveredInstance->Information.Os, DiscoveredInstance->Information.OsVersion));\r | |
7e7b729f | 759 | }\r |
39de741e | 760 | \r |
7e7b729f | 761 | if (OsVer != NULL) {\r |
39de741e MK |
762 | DiscoveredInstance->Information.OsVersion = (CHAR16 *)AllocatePool (AsciiStrSize ((const CHAR8 *)OsVer) * sizeof (CHAR16));\r |
763 | AsciiStrToUnicodeStrS ((const CHAR8 *)OsVer, DiscoveredInstance->Information.OsVersion, AsciiStrSize ((const CHAR8 *)OsVer) * sizeof (CHAR16));\r | |
7e7b729f | 764 | }\r |
39de741e MK |
765 | \r |
766 | if ((Product != NULL) && (ProductVer != NULL)) {\r | |
767 | DiscoveredInstance->Information.Product = (CHAR16 *)AllocatePool (AsciiStrSize ((const CHAR8 *)Product) * sizeof (CHAR16));\r | |
768 | AsciiStrToUnicodeStrS ((const CHAR8 *)Product, DiscoveredInstance->Information.Product, AsciiStrSize ((const CHAR8 *)Product) * sizeof (CHAR16));\r | |
769 | DiscoveredInstance->Information.ProductVer = (CHAR16 *)AllocatePool (AsciiStrSize ((const CHAR8 *)ProductVer) * sizeof (CHAR16));\r | |
770 | AsciiStrToUnicodeStrS ((const CHAR8 *)ProductVer, DiscoveredInstance->Information.ProductVer, AsciiStrSize ((const CHAR8 *)ProductVer) * sizeof (CHAR16));\r | |
771 | DEBUG ((DEBUG_INFO, "Redfish service product: %s, Version:%s.\n", DiscoveredInstance->Information.Product, DiscoveredInstance->Information.ProductVer));\r | |
7e7b729f AC |
772 | }\r |
773 | \r | |
774 | if (RedfishLocation == NULL) {\r | |
775 | // This is the Redfish reported from SMBIOS 42h\r | |
776 | // without validation.\r | |
777 | \r | |
39de741e | 778 | IP4_COPY_ADDRESS ((VOID *)&DiscoveredInstance->Information.RedfishHostIpAddress.v4, (VOID *)&Instance->TargetIpAddress.v4);\r |
7e7b729f | 779 | }\r |
39de741e | 780 | \r |
7e7b729f AC |
781 | if (!InfoRefresh) {\r |
782 | DiscoveredList->Instance = DiscoveredInstance;\r | |
39de741e | 783 | InsertTailList (&mRedfishInstanceList, &DiscoveredList->NextInstance);\r |
7e7b729f | 784 | }\r |
39de741e | 785 | \r |
7e7b729f AC |
786 | DiscoveredInstance->Status = EFI_SUCCESS;\r |
787 | } else {\r | |
788 | if (DiscoveredList != NULL) {\r | |
39de741e | 789 | DEBUG ((DEBUG_INFO, "*** This Redfish Service was already found ***\n"));\r |
7e7b729f | 790 | if (DiscoveredInstance->Information.Uuid != NULL) {\r |
39de741e | 791 | DEBUG ((DEBUG_INFO, "Service UUID: %s.\n", DiscoveredInstance->Information.Uuid));\r |
7e7b729f | 792 | } else {\r |
39de741e | 793 | DEBUG ((DEBUG_INFO, "Service UUID: unknown.\n"));\r |
7e7b729f AC |
794 | }\r |
795 | }\r | |
796 | }\r | |
39de741e | 797 | \r |
7e7b729f | 798 | if (Char16Uuid != NULL) {\r |
39de741e | 799 | FreePool ((VOID *)Char16Uuid);\r |
7e7b729f AC |
800 | }\r |
801 | \r | |
802 | Status = EFI_SUCCESS;\r | |
803 | if (NewFound || InfoRefresh) {\r | |
804 | //\r | |
805 | // Build up EFI_REDFISH_DISCOVERED_LIST in token.\r | |
806 | //\r | |
807 | Instance->DiscoverToken->DiscoverList.NumberOfServiceFound = 1;\r | |
39de741e MK |
808 | Instance->DiscoverToken->DiscoverList.RedfishInstances = DiscoveredInstance;\r |
809 | DiscoveredInstance->Status = EFI_SUCCESS;\r | |
7e7b729f AC |
810 | if (!InfoRefresh) {\r |
811 | Status = CreateRestExInstance (Instance, Instance->DiscoverToken); // Create REST EX child.\r | |
812 | if (EFI_ERROR (Status)) {\r | |
39de741e | 813 | DEBUG ((DEBUG_ERROR, "%a:Can't create REST EX child instance.\n", __FUNCTION__));\r |
7e7b729f AC |
814 | goto ON_EXIT;\r |
815 | }\r | |
39de741e MK |
816 | \r |
817 | Status = gBS->OpenProtocol (\r | |
818 | // Configure local host information.\r | |
819 | Instance->DiscoverToken->DiscoverList.RedfishInstances->Information.RedfishRestExHandle,\r | |
820 | &gEfiRestExProtocolGuid,\r | |
821 | (VOID **)&RestEx,\r | |
822 | Instance->NetworkInterface->OpenDriverAgentHandle,\r | |
823 | Instance->NetworkInterface->OpenDriverControllerHandle,\r | |
824 | EFI_OPEN_PROTOCOL_BY_DRIVER\r | |
825 | );\r | |
7e7b729f AC |
826 | if (EFI_ERROR (Status)) {\r |
827 | DeleteRestEx = TRUE;\r | |
828 | goto ERROR_EXIT;\r | |
829 | }\r | |
39de741e MK |
830 | \r |
831 | RestExOpened = TRUE;\r | |
7e7b729f AC |
832 | RestExHttpConfigData = AllocateZeroPool (sizeof (EFI_REST_EX_HTTP_CONFIG_DATA));\r |
833 | if (RestExHttpConfigData == NULL) {\r | |
39de741e | 834 | Status = EFI_OUT_OF_RESOURCES;\r |
7e7b729f AC |
835 | DeleteRestEx = TRUE;\r |
836 | goto EXIT_FREE_CONFIG_DATA;\r | |
837 | }\r | |
39de741e MK |
838 | \r |
839 | RestExHttpConfigData->SendReceiveTimeout = 5000;\r | |
840 | RestExHttpConfigData->HttpConfigData.HttpVersion = HttpVersion11;\r | |
841 | RestExHttpConfigData->HttpConfigData.LocalAddressIsIPv6 = CheckIsIpVersion6 (NetworkInterface);\r | |
7e7b729f AC |
842 | if (RestExHttpConfigData->HttpConfigData.LocalAddressIsIPv6) {\r |
843 | RestExHttpConfigData->HttpConfigData.AccessPoint.IPv6Node = AllocateZeroPool (sizeof (EFI_HTTPv6_ACCESS_POINT));\r | |
844 | if (RestExHttpConfigData->HttpConfigData.AccessPoint.IPv6Node == NULL) {\r | |
845 | Status = EFI_OUT_OF_RESOURCES;\r | |
846 | goto EXIT_FREE_CONFIG_DATA;\r | |
847 | }\r | |
848 | } else {\r | |
849 | RestExHttpConfigData->HttpConfigData.AccessPoint.IPv4Node = AllocateZeroPool (sizeof (EFI_HTTPv4_ACCESS_POINT));\r | |
850 | if (RestExHttpConfigData->HttpConfigData.AccessPoint.IPv4Node == NULL) {\r | |
851 | Status = EFI_OUT_OF_RESOURCES;\r | |
852 | goto EXIT_FREE_CONFIG_DATA;\r | |
853 | }\r | |
39de741e | 854 | \r |
7e7b729f AC |
855 | RestExHttpConfigData->HttpConfigData.AccessPoint.IPv4Node->UseDefaultAddress = TRUE;\r |
856 | }\r | |
39de741e | 857 | \r |
7e7b729f | 858 | Status = RestEx->Configure (\r |
39de741e MK |
859 | RestEx,\r |
860 | (EFI_REST_EX_CONFIG_DATA)(UINT8 *)RestExHttpConfigData\r | |
861 | );\r | |
7e7b729f | 862 | if (EFI_ERROR (Status)) {\r |
39de741e | 863 | DEBUG ((DEBUG_ERROR, "%a:REST EX configured..\n", __FUNCTION__));\r |
7e7b729f AC |
864 | DeleteRestEx = TRUE;\r |
865 | goto EXIT_FREE_ALL;\r | |
866 | }\r | |
39de741e | 867 | \r |
7e7b729f AC |
868 | //\r |
869 | // Signal client, close REST EX before signaling client.\r | |
870 | //\r | |
871 | if (RestExOpened) {\r | |
39de741e MK |
872 | gBS->CloseProtocol (\r |
873 | Instance->DiscoverToken->DiscoverList.RedfishInstances->Information.RedfishRestExHandle,\r | |
874 | &gEfiRestExProtocolGuid,\r | |
875 | Instance->NetworkInterface->OpenDriverAgentHandle,\r | |
876 | Instance->NetworkInterface->OpenDriverControllerHandle\r | |
877 | );\r | |
7e7b729f AC |
878 | RestExOpened = FALSE;\r |
879 | }\r | |
880 | }\r | |
39de741e MK |
881 | \r |
882 | Status = gBS->SignalEvent (Instance->DiscoverToken->Event);\r | |
7e7b729f | 883 | if (!EFI_ERROR (Status)) {\r |
39de741e | 884 | DEBUG ((DEBUG_ERROR, "%a:No event to signal!\n", __FUNCTION__));\r |
7e7b729f AC |
885 | }\r |
886 | }\r | |
887 | \r | |
888 | EXIT_FREE_ALL:;\r | |
39de741e | 889 | if ((RestExHttpConfigData != NULL) && (RestExHttpConfigData->HttpConfigData.AccessPoint.IPv4Node != NULL)) {\r |
7e7b729f AC |
890 | FreePool (RestExHttpConfigData->HttpConfigData.AccessPoint.IPv4Node);\r |
891 | }\r | |
892 | \r | |
893 | EXIT_FREE_CONFIG_DATA:;\r | |
894 | if (RestExHttpConfigData != NULL) {\r | |
39de741e | 895 | FreePool ((VOID *)RestExHttpConfigData);\r |
7e7b729f | 896 | }\r |
39de741e | 897 | \r |
7e7b729f | 898 | if (RestExOpened) {\r |
39de741e | 899 | gBS->CloseProtocol (\r |
7e7b729f AC |
900 | Instance->DiscoverToken->DiscoverList.RedfishInstances->Information.RedfishRestExHandle,\r |
901 | &gEfiRestExProtocolGuid,\r | |
902 | Instance->NetworkInterface->OpenDriverAgentHandle,\r | |
903 | Instance->NetworkInterface->OpenDriverControllerHandle\r | |
39de741e | 904 | );\r |
7e7b729f | 905 | }\r |
39de741e | 906 | \r |
7e7b729f | 907 | ERROR_EXIT:;\r |
39de741e MK |
908 | if (DeleteRestEx && RestExOpened) {\r |
909 | gBS->CloseProtocol (\r | |
7e7b729f AC |
910 | Instance->DiscoverToken->DiscoverList.RedfishInstances->Information.RedfishRestExHandle,\r |
911 | &gEfiRestExProtocolGuid,\r | |
912 | Instance->NetworkInterface->OpenDriverAgentHandle,\r | |
913 | Instance->NetworkInterface->OpenDriverControllerHandle\r | |
39de741e MK |
914 | );\r |
915 | }\r | |
916 | \r | |
7e7b729f AC |
917 | ON_EXIT:;\r |
918 | return Status;\r | |
919 | }\r | |
920 | \r | |
921 | /**\r | |
922 | This function gets the subnet information of this network interface instance.\r | |
923 | can discover Redfish service on it.\r | |
924 | \r | |
925 | @param[in] Instance EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL instance.\r | |
926 | @param[in] ImageHandle EFI Image handle request the network interface list.\r | |
927 | \r | |
928 | @retval EFI_SUCCESS\r | |
929 | \r | |
930 | **/\r | |
931 | EFI_STATUS\r | |
932 | NetworkInterfaceGetSubnetInfo (\r | |
39de741e MK |
933 | IN EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *Instance,\r |
934 | IN EFI_HANDLE ImageHandle\r | |
7e7b729f AC |
935 | )\r |
936 | {\r | |
39de741e MK |
937 | EFI_STATUS Status;\r |
938 | UINT32 ProtocolType;\r | |
939 | UINT32 IPv6InfoIndex;\r | |
940 | EFI_IP6_ADDRESS_INFO *ThisSubnetAddrInfoIPv6;\r | |
941 | EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *NewNetworkInterface;\r | |
7e7b729f AC |
942 | \r |
943 | if (Instance->GotSubnetInfo) {\r | |
944 | return EFI_SUCCESS;\r | |
945 | }\r | |
946 | \r | |
947 | ProtocolType = Instance->NetworkProtocolType;\r | |
39de741e MK |
948 | if ((gRequiredProtocol[ProtocolType].GetSubnetInfo != NULL) && (Instance->GotSubnetInfo == FALSE)) {\r |
949 | Status = gRequiredProtocol[ProtocolType].GetSubnetInfo (\r | |
950 | ImageHandle,\r | |
951 | Instance\r | |
952 | );\r | |
7e7b729f | 953 | if (EFI_ERROR (Status)) {\r |
39de741e | 954 | DEBUG ((DEBUG_ERROR, "%a:Faile to get Subnet infomation.\n", __FUNCTION__));\r |
7e7b729f AC |
955 | return Status;\r |
956 | } else {\r | |
39de741e | 957 | DEBUG ((DEBUG_INFO, "%a:MAC address: %s\n", __FUNCTION__, Instance->StrMacAddr));\r |
7e7b729f AC |
958 | if (CheckIsIpVersion6 (Instance)) {\r |
959 | if (Instance->SubnetAddrInfoIPv6Number == 0) {\r | |
39de741e | 960 | DEBUG ((DEBUG_ERROR, "%a: There is no Subnet infomation for IPv6 network interface.\n", __FUNCTION__));\r |
7e7b729f AC |
961 | return EFI_NOT_FOUND;\r |
962 | }\r | |
39de741e | 963 | \r |
7e7b729f AC |
964 | ThisSubnetAddrInfoIPv6 = Instance->SubnetAddrInfoIPv6; // First IPv6 address information.\r |
965 | IP6_COPY_ADDRESS (&Instance->SubnetAddr.v6, &ThisSubnetAddrInfoIPv6->Address);\r | |
966 | Instance->SubnetPrefixLength = ThisSubnetAddrInfoIPv6->PrefixLength;\r | |
39de741e MK |
967 | DEBUG ((\r |
968 | DEBUG_INFO,\r | |
969 | " IPv6 Subnet ID:%d, Prefix length: %d.\n",\r | |
970 | ThisSubnetAddrInfoIPv6->Address.Addr[7] + (UINT16)ThisSubnetAddrInfoIPv6->Address.Addr[6] * 256,\r | |
971 | ThisSubnetAddrInfoIPv6->PrefixLength\r | |
972 | )\r | |
973 | );\r | |
7e7b729f AC |
974 | //\r |
975 | // If this is IPv6, then we may have to propagate network interface for IPv6 network scopes\r | |
976 | // according to the Ipv6 address information.\r | |
977 | //\r | |
39de741e | 978 | ThisSubnetAddrInfoIPv6++;\r |
7e7b729f AC |
979 | for (IPv6InfoIndex = 0; IPv6InfoIndex < Instance->SubnetAddrInfoIPv6Number - 1; IPv6InfoIndex++) {\r |
980 | //\r | |
981 | // Build up addtional EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL instances.\r | |
982 | //\r | |
983 | NewNetworkInterface = (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *)AllocateZeroPool (sizeof (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL));\r | |
984 | if (NewNetworkInterface != NULL) {\r | |
985 | CopyMem ((VOID *)NewNetworkInterface, (VOID *)Instance, sizeof (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL)); // Clone information of first instance.\r | |
986 | IP6_COPY_ADDRESS (&NewNetworkInterface->SubnetAddr.v6, &ThisSubnetAddrInfoIPv6->Address);\r | |
987 | NewNetworkInterface->SubnetPrefixLength = ThisSubnetAddrInfoIPv6->PrefixLength;\r | |
39de741e | 988 | NewNetworkInterface->GotSubnetInfo = TRUE;\r |
7e7b729f | 989 | InsertTailList (&mEfiRedfishDiscoverNetworkInterface, &NewNetworkInterface->Entry);\r |
39de741e MK |
990 | ThisSubnetAddrInfoIPv6++;\r |
991 | mNumNetworkInterface++;\r | |
992 | DEBUG ((\r | |
993 | DEBUG_INFO,\r | |
994 | " IPv6 Subnet ID:%d, Prefix length: %d.\n",\r | |
995 | ThisSubnetAddrInfoIPv6->Address.Addr[7] + (UINT16)ThisSubnetAddrInfoIPv6->Address.Addr[6] * 256,\r | |
996 | ThisSubnetAddrInfoIPv6->PrefixLength\r | |
997 | )\r | |
998 | );\r | |
7e7b729f AC |
999 | } else {\r |
1000 | return EFI_OUT_OF_RESOURCES;\r | |
1001 | }\r | |
1002 | }\r | |
1003 | } else {\r | |
39de741e MK |
1004 | DEBUG ((\r |
1005 | DEBUG_INFO,\r | |
1006 | " IPv4 Subnet:%d.%d.%d.%d Subnet mask: %d.%d.%d.%d.\n",\r | |
1007 | Instance->SubnetAddr.v4.Addr[0],\r | |
1008 | Instance->SubnetAddr.v4.Addr[1],\r | |
1009 | Instance->SubnetAddr.v4.Addr[2],\r | |
1010 | Instance->SubnetAddr.v4.Addr[3],\r | |
1011 | Instance->SubnetMask.v4.Addr[0],\r | |
1012 | Instance->SubnetMask.v4.Addr[1],\r | |
1013 | Instance->SubnetMask.v4.Addr[2],\r | |
1014 | Instance->SubnetMask.v4.Addr[3]\r | |
1015 | ));\r | |
7e7b729f AC |
1016 | }\r |
1017 | }\r | |
1018 | }\r | |
39de741e | 1019 | \r |
7e7b729f AC |
1020 | Instance->GotSubnetInfo = TRUE; // Only try to get Subnet Info once.\r |
1021 | return EFI_SUCCESS;\r | |
1022 | }\r | |
1023 | \r | |
1024 | /**\r | |
1025 | This function gets the network interface list which Redfish discover protocol\r | |
1026 | can discover Redfish service on it.\r | |
1027 | \r | |
1028 | @param[in] This EFI_REDFISH_DISCOVER_PROTOCOL instance.\r | |
1029 | @param[in] ImageHandle EFI Image handle request the network interface list,\r | |
1030 | @param[out] NumberOfNetworkIntfs Number of network interfaces can do Redfish service discovery.\r | |
1031 | @param[out] NetworkIntfInstances Network interface instances. It's an array of instance. The number of entries\r | |
1032 | in array is indicated by NumberOfNetworkIntfs.\r | |
1033 | Caller has to release the memory\r | |
1034 | allocated by Redfish discover protocol.\r | |
1035 | \r | |
1036 | @retval EFI_SUCCESS The information of network interface is returned in NumberOfNetworkIntfs and\r | |
1037 | NetworkIntfInstances.\r | |
1038 | @retval Others Fail to return the information of network interface.\r | |
1039 | \r | |
1040 | **/\r | |
1041 | EFI_STATUS\r | |
1042 | EFIAPI\r | |
1043 | RedfishServiceGetNetworkInterface (\r | |
39de741e MK |
1044 | IN EFI_REDFISH_DISCOVER_PROTOCOL *This,\r |
1045 | IN EFI_HANDLE ImageHandle,\r | |
1046 | OUT UINTN *NumberOfNetworkIntfs,\r | |
1047 | OUT EFI_REDFISH_DISCOVER_NETWORK_INTERFACE **NetworkIntfInstances\r | |
1048 | )\r | |
7e7b729f | 1049 | {\r |
39de741e MK |
1050 | EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *ThisNetworkInterfaceIntn;\r |
1051 | EFI_REDFISH_DISCOVER_NETWORK_INTERFACE *ThisNetworkInterface;\r | |
7e7b729f | 1052 | \r |
39de741e | 1053 | if ((NetworkIntfInstances == NULL) || (NumberOfNetworkIntfs == NULL) || (ImageHandle == NULL)) {\r |
7e7b729f AC |
1054 | return EFI_INVALID_PARAMETER;\r |
1055 | }\r | |
1056 | \r | |
1057 | *NumberOfNetworkIntfs = 0;\r | |
1058 | *NetworkIntfInstances = NULL;\r | |
1059 | \r | |
39de741e | 1060 | if (IsListEmpty ((const LIST_ENTRY *)&mEfiRedfishDiscoverNetworkInterface)) {\r |
7e7b729f AC |
1061 | return EFI_NOT_FOUND;\r |
1062 | }\r | |
1063 | \r | |
1064 | ThisNetworkInterface = (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE *)AllocateZeroPool (sizeof (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE) * mNumNetworkInterface);\r | |
1065 | if (ThisNetworkInterface == NULL) {\r | |
1066 | return EFI_OUT_OF_RESOURCES;\r | |
1067 | }\r | |
39de741e MK |
1068 | \r |
1069 | *NetworkIntfInstances = ThisNetworkInterface;\r | |
7e7b729f AC |
1070 | ThisNetworkInterfaceIntn = (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *)GetFirstNode (&mEfiRedfishDiscoverNetworkInterface);\r |
1071 | while (TRUE) {\r | |
1072 | ThisNetworkInterface->IsIpv6 = FALSE;\r | |
1073 | if (CheckIsIpVersion6 (ThisNetworkInterfaceIntn)) {\r | |
1074 | ThisNetworkInterface->IsIpv6 = TRUE;\r | |
1075 | }\r | |
39de741e MK |
1076 | \r |
1077 | CopyMem ((VOID *)&ThisNetworkInterface->MacAddress, &ThisNetworkInterfaceIntn->MacAddress, ThisNetworkInterfaceIntn->HwAddressSize);\r | |
1078 | NetworkInterfaceGetSubnetInfo (ThisNetworkInterfaceIntn, ImageHandle); // Get subnet info.\r | |
7e7b729f | 1079 | if (!ThisNetworkInterface->IsIpv6) {\r |
39de741e | 1080 | IP4_COPY_ADDRESS (&ThisNetworkInterface->SubnetId.v4, &ThisNetworkInterfaceIntn->SubnetAddr.v4); // IPv4 subnet information.\r |
7e7b729f AC |
1081 | } else {\r |
1082 | IP6_COPY_ADDRESS (&ThisNetworkInterface->SubnetId.v6, &ThisNetworkInterfaceIntn->SubnetAddr.v6); // IPv6 subnet information in IPv6 address information.\r | |
1083 | }\r | |
39de741e | 1084 | \r |
7e7b729f | 1085 | ThisNetworkInterface->SubnetPrefixLength = ThisNetworkInterfaceIntn->SubnetPrefixLength;\r |
39de741e MK |
1086 | ThisNetworkInterface->VlanId = ThisNetworkInterfaceIntn->VlanId;\r |
1087 | (*NumberOfNetworkIntfs)++;\r | |
7e7b729f AC |
1088 | if (IsNodeAtEnd (&mEfiRedfishDiscoverNetworkInterface, &ThisNetworkInterfaceIntn->Entry)) {\r |
1089 | break;\r | |
1090 | }\r | |
39de741e MK |
1091 | \r |
1092 | ThisNetworkInterfaceIntn = (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *)GetNextNode (&mEfiRedfishDiscoverNetworkInterface, &ThisNetworkInterfaceIntn->Entry);\r | |
1093 | ThisNetworkInterface++;\r | |
1094 | }\r | |
1095 | \r | |
7e7b729f AC |
1096 | return EFI_SUCCESS;\r |
1097 | }\r | |
39de741e | 1098 | \r |
7e7b729f AC |
1099 | /**\r |
1100 | This function acquires Redfish services by discovering static Redfish setting\r | |
1101 | according to Redfish Host Interface or through SSDP. Returns a list of EFI\r | |
1102 | handles in EFI_REDFISH_DISCOVERED_LIST. Each of EFI handle has cooresponding\r | |
1103 | EFI REST EX instance installed on it. Each REST EX isntance is a child instance which\r | |
1104 | created through EFI REST EX serivce protoocl for communicating with specific\r | |
1105 | Redfish service.\r | |
1106 | \r | |
1107 | @param[in] This EFI_REDFISH_DISCOVER_PROTOCOL instance.\r | |
1108 | @param[in] ImageHandle EFI image owns these Redfish service instances.\r | |
1109 | @param[in] TargetNetworkInterface Target network interface to do the discovery.\r | |
1110 | NULL means discover Redfish service on all network interfaces on platform.\r | |
1111 | @param[in] Flags Redfish service discover flags.\r | |
1112 | @param[in] Token EFI_REDFISH_DISCOVERED_TOKEN instance.\r | |
1113 | The memory of EFI_REDFISH_DISCOVERED_LIST and the strings in\r | |
1114 | EFI_REDFISH_DISCOVERED_INFORMATION are all allocated by Acquire()\r | |
1115 | and must be freed when caller invoke Release().\r | |
1116 | \r | |
1117 | @retval EFI_SUCCESS REST EX instance of discovered Redfish services are returned.\r | |
1118 | @retval EFI_INVALID_PARAMETERS ImageHandle == NULL, Flags == 0, Token == NULL, Token->Timeout > 5,\r | |
1119 | or Token->Event == NULL.\r | |
1120 | @retval Others Fail acquire Redfish services.\r | |
1121 | \r | |
1122 | **/\r | |
1123 | EFI_STATUS\r | |
1124 | EFIAPI\r | |
1125 | RedfishServiceAcquireService (\r | |
39de741e MK |
1126 | IN EFI_REDFISH_DISCOVER_PROTOCOL *This,\r |
1127 | IN EFI_HANDLE ImageHandle,\r | |
7e7b729f | 1128 | IN EFI_REDFISH_DISCOVER_NETWORK_INTERFACE *TargetNetworkInterface,\r |
39de741e MK |
1129 | IN EFI_REDFISH_DISCOVER_FLAG Flags,\r |
1130 | IN EFI_REDFISH_DISCOVERED_TOKEN *Token\r | |
7e7b729f AC |
1131 | )\r |
1132 | {\r | |
39de741e MK |
1133 | EFI_REDFISH_DISCOVERED_INTERNAL_INSTANCE *Instance;\r |
1134 | EFI_STATUS Status1;\r | |
1135 | EFI_STATUS Status2;\r | |
1136 | BOOLEAN NewInstance;\r | |
1137 | UINTN NumNetworkInterfaces;\r | |
1138 | UINTN NetworkInterfacesIndex;\r | |
1139 | EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *TargetNetworkInterfaceInternal;\r | |
7e7b729f | 1140 | \r |
39de741e | 1141 | DEBUG ((DEBUG_INFO, "%a:Entry.\n", __FUNCTION__));\r |
7e7b729f AC |
1142 | \r |
1143 | //\r | |
1144 | // Validate parameters.\r | |
1145 | //\r | |
39de741e MK |
1146 | if ((ImageHandle == NULL) || (Token == NULL) || ((Flags & ~EFI_REDFISH_DISCOVER_VALIDATION) == 0)) {\r |
1147 | DEBUG ((DEBUG_ERROR, "%a:Invalid parameters.\n", __FUNCTION__));\r | |
7e7b729f AC |
1148 | return EFI_INVALID_PARAMETER;\r |
1149 | }\r | |
39de741e | 1150 | \r |
7e7b729f AC |
1151 | //\r |
1152 | // Validate target network interface.\r | |
1153 | //\r | |
1154 | if (EFI_ERROR (ValidateTargetNetworkInterface (TargetNetworkInterface, Flags))) {\r | |
39de741e | 1155 | return EFI_UNSUPPORTED;\r |
7e7b729f | 1156 | }\r |
39de741e | 1157 | \r |
7e7b729f AC |
1158 | if (TargetNetworkInterface != NULL) {\r |
1159 | TargetNetworkInterfaceInternal = GetTargetNetworkInterfaceInternal (TargetNetworkInterface);\r | |
39de741e | 1160 | NumNetworkInterfaces = 1;\r |
7e7b729f AC |
1161 | } else {\r |
1162 | TargetNetworkInterfaceInternal = (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *)GetFirstNode (&mEfiRedfishDiscoverNetworkInterface);\r | |
39de741e | 1163 | NumNetworkInterfaces = NumberOfNetworkInterface ();\r |
7e7b729f | 1164 | if (NumNetworkInterfaces == 0) {\r |
39de741e | 1165 | DEBUG ((DEBUG_ERROR, "%a:No network interface on platform.\n", __FUNCTION__));\r |
7e7b729f AC |
1166 | return EFI_UNSUPPORTED;\r |
1167 | }\r | |
1168 | }\r | |
39de741e MK |
1169 | \r |
1170 | for (NetworkInterfacesIndex = 0; NetworkInterfacesIndex < NumNetworkInterfaces; NetworkInterfacesIndex++) {\r | |
1171 | Status1 = EFI_SUCCESS;\r | |
1172 | Status2 = EFI_SUCCESS;\r | |
7e7b729f | 1173 | NewInstance = FALSE;\r |
39de741e | 1174 | Instance = GetInstanceByOwner (ImageHandle, TargetNetworkInterfaceInternal, Flags & ~EFI_REDFISH_DISCOVER_VALIDATION); // Check if we can re-use previous instance.\r |
7e7b729f | 1175 | if (Instance == NULL) {\r |
39de741e MK |
1176 | DEBUG ((DEBUG_INFO, "%a:Create new EFI_REDFISH_DISCOVERED_INTERNAL_INSTANCE.\n", __FUNCTION__));\r |
1177 | Instance = (EFI_REDFISH_DISCOVERED_INTERNAL_INSTANCE *)AllocateZeroPool (sizeof (EFI_REDFISH_DISCOVERED_INTERNAL_INSTANCE));\r | |
7e7b729f | 1178 | if (Instance == NULL) {\r |
39de741e | 1179 | DEBUG ((DEBUG_ERROR, "%a:Memory allocation fail.\n", __FUNCTION__));\r |
7e7b729f | 1180 | }\r |
39de741e | 1181 | \r |
7e7b729f | 1182 | InitializeListHead (&Instance->Entry);\r |
39de741e MK |
1183 | Instance->Owner = ImageHandle;\r |
1184 | Instance->DiscoverFlags = Flags & ~EFI_REDFISH_DISCOVER_VALIDATION;\r | |
7e7b729f AC |
1185 | Instance->NetworkInterface = TargetNetworkInterfaceInternal;\r |
1186 | //\r | |
1187 | // Get subnet information in case subnet information is not set because\r | |
1188 | // RedfishServiceGetNetworkInterfaces hasn't been called yet.\r | |
1189 | //\r | |
1190 | NetworkInterfaceGetSubnetInfo (TargetNetworkInterfaceInternal, ImageHandle);\r | |
1191 | NewInstance = TRUE;\r | |
1192 | }\r | |
39de741e | 1193 | \r |
7e7b729f | 1194 | if (TargetNetworkInterfaceInternal->StrMacAddr != NULL) {\r |
39de741e | 1195 | DEBUG ((DEBUG_INFO, "%a:Acquire Redfish service on network interface MAC address:%s.\n", __FUNCTION__, TargetNetworkInterfaceInternal->StrMacAddr));\r |
7e7b729f | 1196 | } else {\r |
39de741e | 1197 | DEBUG ((DEBUG_INFO, "%a:WARNING: No MAC address on this network interface.\n", __FUNCTION__));\r |
7e7b729f AC |
1198 | }\r |
1199 | \r | |
1200 | Instance->DiscoverToken = Token; // Always use the latest Token passed by caller.\r | |
1201 | if ((Flags & EFI_REDFISH_DISCOVER_HOST_INTERFACE) != 0) {\r | |
39de741e | 1202 | DEBUG ((DEBUG_INFO, "%a:Redfish HOST interface discovery.\n", __FUNCTION__));\r |
7e7b729f AC |
1203 | Instance->HostIntfValidation = FALSE;\r |
1204 | if ((Flags & EFI_REDFISH_DISCOVER_VALIDATION) != 0) {\r | |
1205 | Instance->HostIntfValidation = TRUE;\r | |
1206 | }\r | |
39de741e | 1207 | \r |
7e7b729f AC |
1208 | Status1 = DiscoverRedfishHostInterface (Instance); // Discover Redfish service through Redfish Host Interface.\r |
1209 | }\r | |
39de741e | 1210 | \r |
7e7b729f | 1211 | if ((Flags & EFI_REDFISH_DISCOVER_SSDP) != 0) {\r |
39de741e | 1212 | DEBUG ((DEBUG_ERROR, "%a:Redfish service discovery through SSDP is not supported\n", __FUNCTION__));\r |
7e7b729f AC |
1213 | return EFI_UNSUPPORTED;\r |
1214 | } else {\r | |
1215 | if (EFI_ERROR (Status1) && EFI_ERROR (Status2)) {\r | |
1216 | FreePool ((VOID *)Instance);\r | |
39de741e | 1217 | DEBUG ((DEBUG_ERROR, "%a:Something wrong on Redfish service discovery Status1=%x, Status2=%x.\n", __FUNCTION__, Status1, Status2));\r |
7e7b729f AC |
1218 | } else {\r |
1219 | if (NewInstance) {\r | |
39de741e | 1220 | InsertTailList (&mRedfishDiscoverList, &Instance->Entry);\r |
7e7b729f AC |
1221 | }\r |
1222 | }\r | |
1223 | }\r | |
39de741e | 1224 | \r |
7e7b729f AC |
1225 | if (TargetNetworkInterface == NULL) {\r |
1226 | //\r | |
1227 | // Discover Redfish services on all of network interfaces.\r | |
1228 | //\r | |
39de741e | 1229 | TargetNetworkInterfaceInternal = (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *)GetNextNode (&mEfiRedfishDiscoverNetworkInterface, &TargetNetworkInterfaceInternal->Entry);\r |
7e7b729f AC |
1230 | }\r |
1231 | }\r | |
39de741e | 1232 | \r |
7e7b729f AC |
1233 | return EFI_SUCCESS;\r |
1234 | }\r | |
1235 | \r | |
1236 | /**\r | |
1237 | This function aborts Redfish service discovery on the given network interface.\r | |
1238 | \r | |
1239 | @param[in] This EFI_REDFISH_DISCOVER_PROTOCOL instance.\r | |
1240 | @param[in] TargetNetworkInterface Target network interface to do the discovery.\r | |
1241 | \r | |
1242 | @retval EFI_SUCCESS REST EX instance of discovered Redfish services are returned.\r | |
1243 | @retval Others Fail to abort Redfish service discovery.\r | |
1244 | \r | |
1245 | **/\r | |
1246 | EFI_STATUS\r | |
1247 | EFIAPI\r | |
1248 | RedfishServiceAbortAcquire (\r | |
39de741e | 1249 | IN EFI_REDFISH_DISCOVER_PROTOCOL *This,\r |
7e7b729f | 1250 | IN EFI_REDFISH_DISCOVER_NETWORK_INTERFACE *TargetNetworkInterface OPTIONAL\r |
39de741e | 1251 | )\r |
7e7b729f AC |
1252 | {\r |
1253 | // This function is used to abort Redfish service discovery through SSDP\r | |
1254 | // on the network interface. SSDP is optionally supprted by EFI_REDFISH_DISCOVER_PROTOCOL,\r | |
1255 | // we dont have implementation for SSDP now.\r | |
1256 | \r | |
1257 | return EFI_UNSUPPORTED;\r | |
1258 | }\r | |
1259 | \r | |
1260 | /**\r | |
1261 | This function releases Redfish services found by RedfishServiceAcquire().\r | |
1262 | \r | |
1263 | @param[in] This EFI_REDFISH_DISCOVER_PROTOCOL instance.\r | |
1264 | @param[in] InstanceList The Redfish service to release.\r | |
1265 | \r | |
1266 | @retval EFI_SUCCESS REST EX instances of discovered Redfish are released.\r | |
1267 | @retval Others Fail to remove the entry\r | |
1268 | \r | |
1269 | **/\r | |
1270 | EFI_STATUS\r | |
1271 | EFIAPI\r | |
1272 | RedfishServiceReleaseService (\r | |
39de741e MK |
1273 | IN EFI_REDFISH_DISCOVER_PROTOCOL *This,\r |
1274 | IN EFI_REDFISH_DISCOVERED_LIST *InstanceList\r | |
7e7b729f AC |
1275 | )\r |
1276 | {\r | |
39de741e MK |
1277 | UINTN NumService;\r |
1278 | BOOLEAN AnyFailRelease;\r | |
1279 | EFI_REDFISH_DISCOVERED_INSTANCE *ThisRedfishInstance;\r | |
1280 | EFI_REDFISH_DISCOVERED_INTERNAL_LIST *DiscoveredRedfishInstance;\r | |
7e7b729f AC |
1281 | \r |
1282 | if (IsListEmpty (&mRedfishInstanceList)) {\r | |
39de741e | 1283 | DEBUG ((DEBUG_ERROR, "%a:No any discovered Redfish service.\n", __FUNCTION__));\r |
7e7b729f AC |
1284 | return EFI_NOT_FOUND;\r |
1285 | }\r | |
39de741e MK |
1286 | \r |
1287 | AnyFailRelease = FALSE;\r | |
7e7b729f | 1288 | ThisRedfishInstance = InstanceList->RedfishInstances;\r |
39de741e MK |
1289 | for (NumService = 0; NumService < InstanceList->NumberOfServiceFound; NumService++) {\r |
1290 | DiscoveredRedfishInstance = (EFI_REDFISH_DISCOVERED_INTERNAL_LIST *)GetFirstNode (&mRedfishInstanceList);\r | |
7e7b729f AC |
1291 | do {\r |
1292 | if (DiscoveredRedfishInstance->Instance == ThisRedfishInstance) {\r | |
1293 | RemoveEntryList (&DiscoveredRedfishInstance->NextInstance);\r | |
1294 | if (ThisRedfishInstance->Information.Location != NULL) {\r | |
1295 | FreePool (ThisRedfishInstance->Information.Location);\r | |
1296 | }\r | |
39de741e | 1297 | \r |
7e7b729f AC |
1298 | if (ThisRedfishInstance->Information.Uuid != NULL) {\r |
1299 | FreePool (ThisRedfishInstance->Information.Uuid);\r | |
1300 | }\r | |
39de741e | 1301 | \r |
7e7b729f AC |
1302 | if (ThisRedfishInstance->Information.Os != NULL) {\r |
1303 | FreePool (ThisRedfishInstance->Information.Os);\r | |
1304 | }\r | |
39de741e | 1305 | \r |
7e7b729f AC |
1306 | if (ThisRedfishInstance->Information.OsVersion != NULL) {\r |
1307 | FreePool (ThisRedfishInstance->Information.OsVersion);\r | |
1308 | }\r | |
39de741e | 1309 | \r |
7e7b729f AC |
1310 | if (ThisRedfishInstance->Information.Product != NULL) {\r |
1311 | FreePool (ThisRedfishInstance->Information.Product);\r | |
1312 | }\r | |
39de741e | 1313 | \r |
7e7b729f AC |
1314 | if (ThisRedfishInstance->Information.ProductVer != NULL) {\r |
1315 | FreePool (ThisRedfishInstance->Information.ProductVer);\r | |
1316 | }\r | |
39de741e MK |
1317 | \r |
1318 | FreePool ((VOID *)ThisRedfishInstance);\r | |
7e7b729f AC |
1319 | goto ReleaseNext;\r |
1320 | }\r | |
1321 | \r | |
39de741e | 1322 | if (IsNodeAtEnd (&mRedfishInstanceList, &DiscoveredRedfishInstance->NextInstance)) {\r |
7e7b729f AC |
1323 | break;\r |
1324 | }\r | |
39de741e MK |
1325 | \r |
1326 | DiscoveredRedfishInstance = (EFI_REDFISH_DISCOVERED_INTERNAL_LIST *)GetNextNode (&mRedfishInstanceList, &DiscoveredRedfishInstance->NextInstance);\r | |
7e7b729f | 1327 | } while (TRUE);\r |
39de741e | 1328 | \r |
7e7b729f AC |
1329 | AnyFailRelease = TRUE;\r |
1330 | ReleaseNext:;\r | |
1331 | //\r | |
1332 | // Release next discovered Redfish Service.\r | |
1333 | //\r | |
1334 | ThisRedfishInstance = (EFI_REDFISH_DISCOVERED_INSTANCE *)((UINT8 *)ThisRedfishInstance + sizeof (EFI_REDFISH_DISCOVERED_INSTANCE));\r | |
1335 | }\r | |
39de741e | 1336 | \r |
7e7b729f AC |
1337 | if (AnyFailRelease) {\r |
1338 | return EFI_NOT_FOUND;\r | |
1339 | } else {\r | |
1340 | return EFI_SUCCESS;\r | |
1341 | }\r | |
1342 | }\r | |
1343 | \r | |
39de741e | 1344 | EFI_REDFISH_DISCOVER_PROTOCOL mRedfishDiscover = {\r |
7e7b729f AC |
1345 | RedfishServiceGetNetworkInterface,\r |
1346 | RedfishServiceAcquireService,\r | |
1347 | RedfishServiceAbortAcquire,\r | |
1348 | RedfishServiceReleaseService\r | |
1349 | };\r | |
1350 | \r | |
1351 | /**\r | |
1352 | This function create an EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL for the\r | |
1353 | given network interface.\r | |
1354 | \r | |
1355 | \r | |
1356 | @param[in] ControllerHandle MAC address of this network interface.\r | |
1357 | @param[in] NetworkProtocolType Network protocol type.\r | |
1358 | @param[out] IsNewInstance BOOLEAN means new instance or not.\r | |
1359 | @param[out] NetworkInterface Pointer to to EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL.\r | |
1360 | \r | |
1361 | @retval EFI_STATUS\r | |
1362 | **/\r | |
1363 | EFI_STATUS\r | |
1364 | CreateRedfishDiscoverNetworkInterface (\r | |
39de741e MK |
1365 | IN EFI_HANDLE ControllerHandle,\r |
1366 | IN UINT32 NetworkProtocolType,\r | |
1367 | OUT BOOLEAN *IsNewInstance,\r | |
1368 | OUT EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL **NetworkInterface\r | |
7e7b729f AC |
1369 | )\r |
1370 | {\r | |
39de741e MK |
1371 | EFI_MAC_ADDRESS MacAddress;\r |
1372 | UINTN HwAddressSize;\r | |
1373 | EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *ThisNetworkInterface;\r | |
1374 | EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *NewNetworkInterface;\r | |
7e7b729f AC |
1375 | \r |
1376 | NetLibGetMacAddress (ControllerHandle, &MacAddress, &HwAddressSize);\r | |
1377 | NewNetworkInterface = NULL;\r | |
39de741e MK |
1378 | *IsNewInstance = TRUE;\r |
1379 | if (!IsListEmpty ((const LIST_ENTRY *)&mEfiRedfishDiscoverNetworkInterface)) {\r | |
7e7b729f AC |
1380 | //\r |
1381 | // Check if this instance already exist.\r | |
1382 | //\r | |
1383 | ThisNetworkInterface = (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *)GetFirstNode (&mEfiRedfishDiscoverNetworkInterface);\r | |
1384 | if (ThisNetworkInterface != NULL) {\r | |
1385 | while (TRUE) {\r | |
1386 | if ((CompareMem ((CONST VOID *)&ThisNetworkInterface->MacAddress.Addr, (CONST VOID *)&MacAddress.Addr, HwAddressSize) == 0) &&\r | |
39de741e MK |
1387 | (ThisNetworkInterface->NetworkProtocolType == NetworkProtocolType))\r |
1388 | {\r | |
7e7b729f | 1389 | NewNetworkInterface = ThisNetworkInterface;\r |
39de741e | 1390 | *IsNewInstance = FALSE;\r |
7e7b729f AC |
1391 | break;\r |
1392 | }\r | |
39de741e | 1393 | \r |
7e7b729f AC |
1394 | if (IsNodeAtEnd (&mEfiRedfishDiscoverNetworkInterface, &ThisNetworkInterface->Entry)) {\r |
1395 | NewNetworkInterface = NULL;\r | |
1396 | break;\r | |
1397 | }\r | |
39de741e MK |
1398 | \r |
1399 | ThisNetworkInterface = (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *)GetNextNode (&mEfiRedfishDiscoverNetworkInterface, &ThisNetworkInterface->Entry);\r | |
1400 | }\r | |
7e7b729f AC |
1401 | }\r |
1402 | }\r | |
39de741e | 1403 | \r |
7e7b729f AC |
1404 | if (NewNetworkInterface == NULL) {\r |
1405 | //\r | |
1406 | // Create a new instance.\r | |
1407 | //\r | |
1408 | NewNetworkInterface = (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *)AllocateZeroPool (sizeof (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL));\r | |
1409 | if (NewNetworkInterface == NULL) {\r | |
1410 | return EFI_OUT_OF_RESOURCES;\r | |
1411 | }\r | |
39de741e | 1412 | \r |
7e7b729f AC |
1413 | NewNetworkInterface->HwAddressSize = HwAddressSize;\r |
1414 | CopyMem (&NewNetworkInterface->MacAddress.Addr, &MacAddress.Addr, NewNetworkInterface->HwAddressSize);\r | |
1415 | NetLibGetMacString (ControllerHandle, NULL, &NewNetworkInterface->StrMacAddr);\r | |
1416 | NewNetworkInterface->VlanId = NetLibGetVlanId (ControllerHandle);\r | |
1417 | }\r | |
39de741e | 1418 | \r |
7e7b729f AC |
1419 | *NetworkInterface = NewNetworkInterface;\r |
1420 | return EFI_SUCCESS;\r | |
1421 | }\r | |
1422 | \r | |
1423 | /**\r | |
1424 | This function destory network interface\r | |
1425 | \r | |
1426 | \r | |
1427 | @param[in] ThisNetworkInterface EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL instance.\r | |
1428 | \r | |
1429 | @retval EFI_STATUS\r | |
1430 | **/\r | |
1431 | EFI_STATUS\r | |
1432 | DestroyRedfishNetwrokInterface (\r | |
39de741e | 1433 | IN EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *ThisNetworkInterface\r |
7e7b729f AC |
1434 | )\r |
1435 | {\r | |
39de741e | 1436 | EFI_STATUS Status;\r |
7e7b729f | 1437 | \r |
39de741e | 1438 | Status = gBS->UninstallProtocolInterface (\r |
7e7b729f | 1439 | ThisNetworkInterface->OpenDriverControllerHandle,\r |
39de741e | 1440 | gRequiredProtocol[ThisNetworkInterface->NetworkProtocolType].DiscoveredProtocolGuid,\r |
7e7b729f AC |
1441 | &ThisNetworkInterface->NetworkInterfaceProtocolInfo.ProtocolDiscoverId\r |
1442 | );\r | |
1443 | RemoveEntryList (&ThisNetworkInterface->Entry);\r | |
39de741e | 1444 | mNumNetworkInterface--;\r |
7e7b729f AC |
1445 | FreePool (ThisNetworkInterface);\r |
1446 | return Status;\r | |
1447 | }\r | |
1448 | \r | |
1449 | /**\r | |
1450 | Tests to see if the required protocols are provided on the given\r | |
1451 | controller handle.\r | |
1452 | \r | |
1453 | @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.\r | |
1454 | @param[in] ControllerHandle The handle of the controller to test. This handle\r | |
1455 | must support a protocol interface that supplies\r | |
1456 | an I/O abstraction to the driver.\r | |
1457 | @retval EFI_SUCCESS One of required protocol is found.\r | |
1458 | @retval EFI_UNSUPPORTED None of required protocol is found.\r | |
1459 | **/\r | |
1460 | EFI_STATUS\r | |
1461 | TestForRequiredProtocols (\r | |
1462 | IN EFI_DRIVER_BINDING_PROTOCOL *This,\r | |
39de741e | 1463 | IN EFI_HANDLE ControllerHandle\r |
7e7b729f AC |
1464 | )\r |
1465 | {\r | |
39de741e MK |
1466 | UINT32 Id;\r |
1467 | UINTN Index;\r | |
1468 | EFI_STATUS Status;\r | |
7e7b729f | 1469 | \r |
39de741e | 1470 | for (Index = 0; Index < (sizeof (gRequiredProtocol) / sizeof (REDFISH_DISCOVER_REQUIRED_PROTOCOL)); Index++) {\r |
7e7b729f | 1471 | Status = gBS->OpenProtocol (\r |
39de741e MK |
1472 | ControllerHandle,\r |
1473 | gRequiredProtocol[Index].RequiredServiceBindingProtocolGuid,\r | |
1474 | NULL,\r | |
1475 | This->DriverBindingHandle,\r | |
1476 | ControllerHandle,\r | |
1477 | EFI_OPEN_PROTOCOL_TEST_PROTOCOL\r | |
1478 | );\r | |
7e7b729f AC |
1479 | if (!EFI_ERROR (Status)) {\r |
1480 | Status = gBS->OpenProtocol (\r | |
1481 | ControllerHandle,\r | |
39de741e MK |
1482 | gRequiredProtocol[Index].DiscoveredProtocolGuid,\r |
1483 | (VOID **)&Id,\r | |
7e7b729f AC |
1484 | This->DriverBindingHandle,\r |
1485 | ControllerHandle,\r | |
1486 | EFI_OPEN_PROTOCOL_GET_PROTOCOL\r | |
1487 | );\r | |
1488 | if (EFI_ERROR (Status)) {\r | |
39de741e | 1489 | DEBUG ((DEBUG_ERROR, "%a: %s is found on this controller handle.\n", __FUNCTION__, gRequiredProtocol[Index].ProtocolName));\r |
7e7b729f AC |
1490 | return EFI_SUCCESS;\r |
1491 | }\r | |
1492 | }\r | |
1493 | }\r | |
39de741e | 1494 | \r |
7e7b729f AC |
1495 | return EFI_UNSUPPORTED;\r |
1496 | }\r | |
1497 | \r | |
1498 | /**\r | |
1499 | Build up network interface and create corresponding service through the given\r | |
1500 | controller handle.\r | |
1501 | \r | |
1502 | @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.\r | |
1503 | @param[in] ControllerHandle The handle of the controller to test. This handle\r | |
1504 | must support a protocol interface that supplies\r | |
1505 | an I/O abstraction to the driver.\r | |
1506 | @retval EFI_SUCCESS One of required protocol is found.\r | |
1507 | @retval EFI_UNSUPPORTED None of required protocol is found.\r | |
1508 | @retval EFI_UNSUPPORTED Failed to build up network interface.\r | |
1509 | **/\r | |
1510 | EFI_STATUS\r | |
1511 | BuildupNetworkInterface (\r | |
1512 | IN EFI_DRIVER_BINDING_PROTOCOL *This,\r | |
39de741e | 1513 | IN EFI_HANDLE ControllerHandle\r |
7e7b729f AC |
1514 | )\r |
1515 | {\r | |
39de741e MK |
1516 | UINT32 Id;\r |
1517 | UINT32 Index;\r | |
1518 | EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *NetworkInterface;\r | |
1519 | BOOLEAN IsNew;\r | |
1520 | EFI_STATUS Status;\r | |
1521 | VOID *TempInterface;\r | |
1522 | VOID **Interface;\r | |
1523 | UINT32 *ProtocolDiscoverIdPtr;\r | |
1524 | EFI_HANDLE OpenDriverAgentHandle;\r | |
1525 | EFI_HANDLE OpenDriverControllerHandle;\r | |
1526 | EFI_HANDLE *HandleOfProtocolInterfacePtr;\r | |
1527 | EFI_REDFISH_DISCOVER_REST_EX_INSTANCE_INTERNAL *RestExInstance;\r | |
1528 | EFI_TPL OldTpl;\r | |
1529 | BOOLEAN NewNetworkInterfaceInstalled;\r | |
7e7b729f AC |
1530 | \r |
1531 | NewNetworkInterfaceInstalled = FALSE;\r | |
39de741e | 1532 | Index = 0;\r |
7e7b729f | 1533 | do {\r |
39de741e MK |
1534 | Status = gBS->OpenProtocol (\r |
1535 | // Already in list?\r | |
7e7b729f | 1536 | ControllerHandle,\r |
39de741e MK |
1537 | gRequiredProtocol[Index].DiscoveredProtocolGuid,\r |
1538 | (VOID **)&Id,\r | |
7e7b729f AC |
1539 | This->DriverBindingHandle,\r |
1540 | ControllerHandle,\r | |
1541 | EFI_OPEN_PROTOCOL_GET_PROTOCOL\r | |
1542 | );\r | |
1543 | if (!EFI_ERROR (Status)) {\r | |
39de741e MK |
1544 | Index++;\r |
1545 | if (Index == (sizeof (gRequiredProtocol) / sizeof (REDFISH_DISCOVER_REQUIRED_PROTOCOL))) {\r | |
7e7b729f AC |
1546 | break;\r |
1547 | }\r | |
39de741e | 1548 | \r |
7e7b729f AC |
1549 | continue;\r |
1550 | }\r | |
1551 | \r | |
1552 | Status = gBS->OpenProtocol (\r | |
1553 | ControllerHandle,\r | |
39de741e | 1554 | gRequiredProtocol[Index].RequiredServiceBindingProtocolGuid,\r |
7e7b729f AC |
1555 | &TempInterface,\r |
1556 | This->DriverBindingHandle,\r | |
1557 | ControllerHandle,\r | |
1558 | EFI_OPEN_PROTOCOL_GET_PROTOCOL\r | |
1559 | );\r | |
1560 | if (EFI_ERROR (Status)) {\r | |
39de741e MK |
1561 | Index++;\r |
1562 | if (Index == (sizeof (gRequiredProtocol) / sizeof (REDFISH_DISCOVER_REQUIRED_PROTOCOL))) {\r | |
7e7b729f AC |
1563 | break;\r |
1564 | }\r | |
39de741e | 1565 | \r |
7e7b729f AC |
1566 | continue;\r |
1567 | }\r | |
39de741e MK |
1568 | \r |
1569 | if (gRequiredProtocol[Index].ProtocolType != ProtocolTypeRestEx) {\r | |
7e7b729f | 1570 | OldTpl = gBS->RaiseTPL (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_TPL);\r |
39de741e | 1571 | Status = CreateRedfishDiscoverNetworkInterface (ControllerHandle, gRequiredProtocol[Index].ProtocolType, &IsNew, &NetworkInterface);\r |
7e7b729f AC |
1572 | if (EFI_ERROR (Status)) {\r |
1573 | gBS->RestoreTPL (OldTpl);\r | |
1574 | return Status;\r | |
1575 | }\r | |
39de741e MK |
1576 | \r |
1577 | NetworkInterface->NetworkProtocolType = gRequiredProtocol[Index].ProtocolType;\r | |
1578 | NetworkInterface->OpenDriverAgentHandle = This->DriverBindingHandle;\r | |
1579 | NetworkInterface->OpenDriverControllerHandle = ControllerHandle;\r | |
7e7b729f | 1580 | NetworkInterface->NetworkInterfaceProtocolInfo.ProtocolGuid = \\r |
39de741e | 1581 | *gRequiredProtocol[Index].RequiredProtocolGuid;\r |
7e7b729f | 1582 | NetworkInterface->NetworkInterfaceProtocolInfo.ProtocolServiceGuid = \\r |
39de741e MK |
1583 | *gRequiredProtocol[Index].RequiredServiceBindingProtocolGuid;\r |
1584 | ProtocolDiscoverIdPtr = &NetworkInterface->NetworkInterfaceProtocolInfo.ProtocolDiscoverId;\r | |
1585 | OpenDriverAgentHandle = NetworkInterface->OpenDriverAgentHandle;\r | |
1586 | OpenDriverControllerHandle = NetworkInterface->OpenDriverControllerHandle;\r | |
7e7b729f | 1587 | HandleOfProtocolInterfacePtr = &NetworkInterface->NetworkInterfaceProtocolInfo.ProtocolControllerHandle;\r |
39de741e | 1588 | Interface = &NetworkInterface->NetworkInterfaceProtocolInfo.NetworkProtocolInterface;\r |
7e7b729f AC |
1589 | NewNetworkInterfaceInstalled = TRUE;\r |
1590 | if (IsNew) {\r | |
1591 | InsertTailList (&mEfiRedfishDiscoverNetworkInterface, &NetworkInterface->Entry);\r | |
39de741e | 1592 | mNumNetworkInterface++;\r |
7e7b729f | 1593 | }\r |
39de741e | 1594 | \r |
7e7b729f AC |
1595 | gBS->RestoreTPL (OldTpl);\r |
1596 | } else {\r | |
1597 | // Record REST_EX instance. REST_EX is created when clinet asks for Redfish service discovery.\r | |
1598 | // Redfish Service Discover protocol will match REST EX to the corresponding EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL\r | |
1599 | // when discovery.\r | |
1600 | \r | |
1601 | RestExInstance = (EFI_REDFISH_DISCOVER_REST_EX_INSTANCE_INTERNAL *)AllocateZeroPool (sizeof (EFI_REDFISH_DISCOVER_REST_EX_INSTANCE_INTERNAL));\r | |
1602 | if (RestExInstance == NULL) {\r | |
1603 | return EFI_OUT_OF_RESOURCES;\r | |
1604 | }\r | |
39de741e MK |
1605 | \r |
1606 | RestExInstance->OpenDriverAgentHandle = This->DriverBindingHandle;\r | |
7e7b729f | 1607 | RestExInstance->OpenDriverControllerHandle = ControllerHandle;\r |
39de741e | 1608 | RestExInstance->RestExControllerHandle = ControllerHandle;\r |
7e7b729f AC |
1609 | InitializeListHead (&RestExInstance->Entry);\r |
1610 | InsertTailList (&mEfiRedfishDiscoverRestExInstance, &RestExInstance->Entry);\r | |
39de741e MK |
1611 | mNumRestExInstance++;\r |
1612 | ProtocolDiscoverIdPtr = &RestExInstance->RestExId;\r | |
1613 | OpenDriverAgentHandle = RestExInstance->OpenDriverAgentHandle;\r | |
1614 | OpenDriverControllerHandle = RestExInstance->OpenDriverControllerHandle;\r | |
7e7b729f | 1615 | HandleOfProtocolInterfacePtr = &RestExInstance->RestExChildHandle;\r |
39de741e | 1616 | Interface = (VOID **)&RestExInstance->RestExProtocolInterface;\r |
7e7b729f | 1617 | }\r |
39de741e | 1618 | \r |
7e7b729f AC |
1619 | Status = gBS->InstallProtocolInterface (\r |
1620 | &ControllerHandle,\r | |
39de741e | 1621 | gRequiredProtocol[Index].DiscoveredProtocolGuid,\r |
7e7b729f AC |
1622 | EFI_NATIVE_INTERFACE,\r |
1623 | ProtocolDiscoverIdPtr\r | |
1624 | );\r | |
1625 | if (EFI_ERROR (Status)) {\r | |
39de741e MK |
1626 | Index++;\r |
1627 | if (Index == (sizeof (gRequiredProtocol) / sizeof (REDFISH_DISCOVER_REQUIRED_PROTOCOL))) {\r | |
7e7b729f AC |
1628 | break;\r |
1629 | }\r | |
39de741e | 1630 | \r |
7e7b729f AC |
1631 | continue;\r |
1632 | }\r | |
39de741e | 1633 | \r |
7e7b729f AC |
1634 | //\r |
1635 | // Create service binding child and open it BY_DRIVER.\r | |
1636 | //\r | |
1637 | Status = NetLibCreateServiceChild (\r | |
39de741e MK |
1638 | ControllerHandle,\r |
1639 | This->ImageHandle,\r | |
1640 | gRequiredProtocol[Index].RequiredServiceBindingProtocolGuid,\r | |
1641 | HandleOfProtocolInterfacePtr\r | |
1642 | );\r | |
7e7b729f AC |
1643 | if (!EFI_ERROR (Status)) {\r |
1644 | Status = gBS->OpenProtocol (\r | |
39de741e MK |
1645 | *HandleOfProtocolInterfacePtr,\r |
1646 | gRequiredProtocol[Index].RequiredProtocolGuid,\r | |
1647 | Interface,\r | |
1648 | OpenDriverAgentHandle,\r | |
1649 | OpenDriverControllerHandle,\r | |
1650 | EFI_OPEN_PROTOCOL_BY_DRIVER\r | |
1651 | );\r | |
7e7b729f | 1652 | if (!EFI_ERROR (Status)) {\r |
f7da805b AC |
1653 | if ((gRequiredProtocol[Index].ProtocolType == ProtocolTypeRestEx)) {\r |
1654 | // Install Redfish Discover Protocol when EFI REST EX protcol is discovered.\r | |
1655 | // This ensures EFI REST EX is ready while the consumer of EFI_REDFISH_DISCOVER_PROTOCOL\r | |
1656 | // acquires Redfish serivce over network interface.\r | |
1657 | \r | |
1658 | if (!NewNetworkInterfaceInstalled) {\r | |
1659 | NetworkInterface = GetTargetNetworkInterfaceInternalByController (ControllerHandle);\r | |
1660 | if (NetworkInterface == NULL) {\r | |
1661 | DEBUG ((DEBUG_ERROR, "%a: Can't find network interface by ControllerHandle\n", __FUNCTION__));\r | |
1662 | return Status;\r | |
1663 | }\r | |
1664 | }\r | |
1665 | \r | |
1666 | NewNetworkInterfaceInstalled = FALSE;\r | |
1667 | NetworkInterface->EfiRedfishDiscoverProtocolHandle = NULL;\r | |
1668 | Status = gBS->InstallProtocolInterface (\r | |
1669 | &NetworkInterface->EfiRedfishDiscoverProtocolHandle,\r | |
1670 | &gEfiRedfishDiscoverProtocolGuid,\r | |
1671 | EFI_NATIVE_INTERFACE,\r | |
1672 | (VOID *)&mRedfishDiscover\r | |
1673 | );\r | |
1674 | if (EFI_ERROR (Status)) {\r | |
1675 | DEBUG ((DEBUG_ERROR, "%a: Fail to install EFI_REDFISH_DISCOVER_PROTOCOL\n", __FUNCTION__));\r | |
1676 | }\r | |
7e7b729f AC |
1677 | }\r |
1678 | }\r | |
39de741e | 1679 | \r |
7e7b729f AC |
1680 | return Status;\r |
1681 | } else {\r | |
39de741e MK |
1682 | Index++;\r |
1683 | if (Index == (sizeof (gRequiredProtocol) / sizeof (REDFISH_DISCOVER_REQUIRED_PROTOCOL))) {\r | |
7e7b729f AC |
1684 | break;\r |
1685 | }\r | |
39de741e | 1686 | \r |
7e7b729f AC |
1687 | continue;\r |
1688 | }\r | |
39de741e MK |
1689 | } while (Index < (sizeof (gRequiredProtocol) / sizeof (REDFISH_DISCOVER_REQUIRED_PROTOCOL)));\r |
1690 | \r | |
7e7b729f AC |
1691 | return EFI_UNSUPPORTED;\r |
1692 | }\r | |
39de741e | 1693 | \r |
7e7b729f AC |
1694 | /**\r |
1695 | Close the protocol opened for Redfish discovery. This function also destories\r | |
1696 | the network services.\r | |
1697 | \r | |
1698 | @param[in] ThisBindingProtocol A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.\r | |
1699 | @param[in] ControllerHandle The handle of the controller to test. This handle\r | |
1700 | must support a protocol interface that supplies\r | |
1701 | an I/O abstraction to the driver.\r | |
1702 | @param[in] ThisRequiredProtocol Pointer to the instance of REDFISH_DISCOVER_REQUIRED_PROTOCOL.\r | |
1703 | @param[in] DriverAgentHandle Driver agent handle which used to open protocol earlier.\r | |
1704 | @param[in] DriverControllerHandle Driver controller handle which used to open protocol earlier.\r | |
1705 | \r | |
1706 | @retval EFI_SUCCESS Prorocol is closed successfully.\r | |
1707 | @retval Others Prorocol is closed unsuccessfully.\r | |
1708 | \r | |
1709 | **/\r | |
1710 | EFI_STATUS\r | |
1711 | CloseProtocolService (\r | |
39de741e MK |
1712 | IN EFI_DRIVER_BINDING_PROTOCOL *ThisBindingProtocol,\r |
1713 | IN EFI_HANDLE ControllerHandle,\r | |
1714 | IN REDFISH_DISCOVER_REQUIRED_PROTOCOL *ThisRequiredProtocol,\r | |
1715 | IN EFI_HANDLE DriverAgentHandle,\r | |
1716 | IN EFI_HANDLE DriverControllerHandle\r | |
1717 | )\r | |
7e7b729f | 1718 | {\r |
39de741e | 1719 | EFI_STATUS Status;\r |
7e7b729f AC |
1720 | \r |
1721 | Status = gBS->CloseProtocol (\r | |
39de741e MK |
1722 | ControllerHandle,\r |
1723 | ThisRequiredProtocol->RequiredProtocolGuid,\r | |
1724 | DriverAgentHandle,\r | |
1725 | DriverControllerHandle\r | |
1726 | );\r | |
7e7b729f | 1727 | if (!EFI_ERROR (Status)) {\r |
39de741e | 1728 | NetLibDestroyServiceChild (\r |
7e7b729f AC |
1729 | ControllerHandle,\r |
1730 | ThisBindingProtocol->ImageHandle,\r | |
1731 | ThisRequiredProtocol->RequiredServiceBindingProtocolGuid,\r | |
1732 | ControllerHandle\r | |
1733 | );\r | |
1734 | }\r | |
39de741e | 1735 | \r |
7e7b729f AC |
1736 | return Status;\r |
1737 | }\r | |
39de741e | 1738 | \r |
7e7b729f AC |
1739 | /**\r |
1740 | Stop the services on network interface.\r | |
1741 | \r | |
1742 | @param[in] ThisBindingProtocol A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.\r | |
1743 | @param[in] ControllerHandle The handle of the controller to test. This handle\r | |
1744 | must support a protocol interface that supplies\r | |
1745 | an I/O abstraction to the driver.\r | |
1746 | @retval EFI_SUCCESS One of required protocol is found.\r | |
1747 | @retval Others Faile to stop the services on network interface.\r | |
1748 | **/\r | |
1749 | EFI_STATUS\r | |
1750 | StopServiceOnNetworkInterface (\r | |
1751 | IN EFI_DRIVER_BINDING_PROTOCOL *ThisBindingProtocol,\r | |
39de741e | 1752 | IN EFI_HANDLE ControllerHandle\r |
7e7b729f AC |
1753 | )\r |
1754 | {\r | |
39de741e MK |
1755 | UINT32 Index;\r |
1756 | EFI_STATUS Status;\r | |
1757 | VOID *Interface;\r | |
1758 | EFI_TPL OldTpl;\r | |
f7da805b | 1759 | EFI_HANDLE DiscoverProtocolHandle;\r |
39de741e MK |
1760 | EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *ThisNetworkInterface;\r |
1761 | EFI_REDFISH_DISCOVER_REST_EX_INSTANCE_INTERNAL *RestExInstance;\r | |
1762 | \r | |
1763 | for (Index = 0; Index < (sizeof (gRequiredProtocol) / sizeof (REDFISH_DISCOVER_REQUIRED_PROTOCOL)); Index++) {\r | |
7e7b729f | 1764 | Status = gBS->HandleProtocol (\r |
39de741e MK |
1765 | ControllerHandle,\r |
1766 | gRequiredProtocol[Index].RequiredProtocolGuid,\r | |
1767 | (VOID **)&Interface\r | |
1768 | );\r | |
7e7b729f | 1769 | if (!EFI_ERROR (Status)) {\r |
39de741e | 1770 | if (gRequiredProtocol[Index].ProtocolType != ProtocolTypeRestEx) {\r |
7e7b729f AC |
1771 | if (IsListEmpty (&mEfiRedfishDiscoverNetworkInterface)) {\r |
1772 | return EFI_NOT_FOUND;\r | |
1773 | }\r | |
39de741e MK |
1774 | \r |
1775 | OldTpl = gBS->RaiseTPL (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_TPL);\r | |
7e7b729f AC |
1776 | ThisNetworkInterface = (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *)GetFirstNode (&mEfiRedfishDiscoverNetworkInterface);\r |
1777 | while (TRUE) {\r | |
1778 | if (ThisNetworkInterface->NetworkInterfaceProtocolInfo.ProtocolControllerHandle == ControllerHandle) {\r | |
f7da805b AC |
1779 | DiscoverProtocolHandle = ThisNetworkInterface->EfiRedfishDiscoverProtocolHandle;\r |
1780 | //\r | |
1781 | // Close protocol and destroy service.\r | |
1782 | //\r | |
39de741e | 1783 | Status = CloseProtocolService (\r |
7e7b729f AC |
1784 | ThisBindingProtocol,\r |
1785 | ControllerHandle,\r | |
39de741e | 1786 | &gRequiredProtocol[Index],\r |
7e7b729f AC |
1787 | ThisNetworkInterface->OpenDriverAgentHandle,\r |
1788 | ThisNetworkInterface->OpenDriverControllerHandle\r | |
1789 | );\r | |
1790 | if (!EFI_ERROR (Status)) {\r | |
1791 | Status = DestroyRedfishNetwrokInterface (ThisNetworkInterface);\r | |
1792 | }\r | |
39de741e | 1793 | \r |
7e7b729f | 1794 | gBS->RestoreTPL (OldTpl);\r |
f7da805b AC |
1795 | \r |
1796 | //\r | |
1797 | // Disconnect EFI Redfish discover driver controller to notify the\r | |
1798 | // clinet which uses .EFI Redfish discover protocol.\r | |
1799 | //\r | |
1800 | if (DiscoverProtocolHandle != NULL) {\r | |
1801 | gBS->DisconnectController (DiscoverProtocolHandle, NULL, NULL);\r | |
1802 | Status = gBS->UninstallProtocolInterface (\r | |
1803 | DiscoverProtocolHandle,\r | |
1804 | &gEfiRedfishDiscoverProtocolGuid,\r | |
1805 | (VOID *)&mRedfishDiscover\r | |
1806 | );\r | |
7e7b729f | 1807 | }\r |
39de741e | 1808 | \r |
7e7b729f AC |
1809 | return Status;\r |
1810 | }\r | |
39de741e | 1811 | \r |
7e7b729f AC |
1812 | if (IsNodeAtEnd (&mEfiRedfishDiscoverNetworkInterface, &ThisNetworkInterface->Entry)) {\r |
1813 | break;\r | |
1814 | }\r | |
39de741e MK |
1815 | \r |
1816 | ThisNetworkInterface = (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *)GetNextNode (&mEfiRedfishDiscoverNetworkInterface, &ThisNetworkInterface->Entry);\r | |
1817 | }\r | |
1818 | \r | |
7e7b729f AC |
1819 | gBS->RestoreTPL (OldTpl);\r |
1820 | } else {\r | |
1821 | if (IsListEmpty (&mEfiRedfishDiscoverRestExInstance)) {\r | |
1822 | return EFI_NOT_FOUND;\r | |
1823 | }\r | |
39de741e MK |
1824 | \r |
1825 | OldTpl = gBS->RaiseTPL (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_TPL);\r | |
7e7b729f AC |
1826 | RestExInstance = (EFI_REDFISH_DISCOVER_REST_EX_INSTANCE_INTERNAL *)GetFirstNode (&mEfiRedfishDiscoverRestExInstance);\r |
1827 | while (TRUE) {\r | |
1828 | if (RestExInstance->RestExChildHandle == ControllerHandle) {\r | |
39de741e MK |
1829 | Status = CloseProtocolService (\r |
1830 | // Close REST_EX protocol.\r | |
7e7b729f AC |
1831 | ThisBindingProtocol,\r |
1832 | ControllerHandle,\r | |
39de741e | 1833 | &gRequiredProtocol[Index],\r |
7e7b729f AC |
1834 | RestExInstance->OpenDriverAgentHandle,\r |
1835 | RestExInstance->OpenDriverControllerHandle\r | |
1836 | );\r | |
1837 | RemoveEntryList (&RestExInstance->Entry);\r | |
1838 | FreePool ((VOID *)RestExInstance);\r | |
39de741e | 1839 | mNumRestExInstance--;\r |
7e7b729f AC |
1840 | gBS->RestoreTPL (OldTpl);\r |
1841 | return Status;\r | |
1842 | }\r | |
39de741e | 1843 | \r |
7e7b729f AC |
1844 | if (IsNodeAtEnd (&mEfiRedfishDiscoverRestExInstance, &RestExInstance->Entry)) {\r |
1845 | break;\r | |
1846 | }\r | |
39de741e MK |
1847 | \r |
1848 | RestExInstance = (EFI_REDFISH_DISCOVER_REST_EX_INSTANCE_INTERNAL *)GetNextNode (&mEfiRedfishDiscoverRestExInstance, &RestExInstance->Entry);\r | |
1849 | }\r | |
1850 | \r | |
7e7b729f AC |
1851 | gBS->RestoreTPL (OldTpl);\r |
1852 | }\r | |
1853 | }\r | |
1854 | }\r | |
39de741e | 1855 | \r |
7e7b729f AC |
1856 | return EFI_NOT_FOUND;\r |
1857 | }\r | |
39de741e | 1858 | \r |
7e7b729f AC |
1859 | /**\r |
1860 | Tests to see if this driver supports a given controller. If a child device is provided,\r | |
1861 | it further tests to see if this driver supports creating a handle for the specified child device.\r | |
1862 | \r | |
1863 | This function checks to see if the driver specified by This supports the device specified by\r | |
1864 | ControllerHandle. Drivers will typically use the device path attached to\r | |
1865 | ControllerHandle and/or the services from the bus I/O abstraction attached to\r | |
1866 | ControllerHandle to determine if the driver supports ControllerHandle. This function\r | |
1867 | may be called many times during platform initialization. In order to reduce boot times, the tests\r | |
1868 | performed by this function must be very small, and take as little time as possible to execute. This\r | |
1869 | function must not change the state of any hardware devices, and this function must be aware that the\r | |
1870 | device specified by ControllerHandle may already be managed by the same driver or a\r | |
1871 | different driver. This function must match its calls to AllocatePages() with FreePages(),\r | |
1872 | AllocatePool() with FreePool(), and OpenProtocol() with CloseProtocol().\r | |
1873 | Because ControllerHandle may have been previously started by the same driver, if a protocol is\r | |
1874 | already in the opened state, then it must not be closed with CloseProtocol(). This is required\r | |
1875 | to guarantee the state of ControllerHandle is not modified by this function.\r | |
1876 | \r | |
1877 | @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.\r | |
1878 | @param[in] ControllerHandle The handle of the controller to test. This handle\r | |
1879 | must support a protocol interface that supplies\r | |
1880 | an I/O abstraction to the driver.\r | |
1881 | @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This\r | |
1882 | parameter is ignored by device drivers, and is optional for bus\r | |
1883 | drivers. For bus drivers, if this parameter is not NULL, then\r | |
1884 | the bus driver must determine if the bus controller specified\r | |
1885 | by ControllerHandle and the child controller specified\r | |
1886 | by RemainingDevicePath are both supported by this\r | |
1887 | bus driver.\r | |
1888 | \r | |
1889 | @retval EFI_SUCCESS The device specified by ControllerHandle and\r | |
1890 | RemainingDevicePath is supported by the driver specified by This.\r | |
1891 | @retval EFI_ALREADY_STARTED The device specified by ControllerHandle and\r | |
1892 | RemainingDevicePath is already being managed by the driver\r | |
1893 | specified by This.\r | |
1894 | @retval EFI_ACCESS_DENIED The device specified by ControllerHandle and\r | |
1895 | RemainingDevicePath is already being managed by a different\r | |
1896 | driver or an application that requires exclusive access.\r | |
1897 | Currently not implemented.\r | |
1898 | @retval EFI_UNSUPPORTED The device specified by ControllerHandle and\r | |
1899 | RemainingDevicePath is not supported by the driver specified by This.\r | |
1900 | **/\r | |
1901 | EFI_STATUS\r | |
1902 | EFIAPI\r | |
1903 | RedfishDiscoverDriverBindingSupported (\r | |
1904 | IN EFI_DRIVER_BINDING_PROTOCOL *This,\r | |
1905 | IN EFI_HANDLE ControllerHandle,\r | |
1906 | IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL\r | |
1907 | )\r | |
1908 | {\r | |
1909 | return TestForRequiredProtocols (This, ControllerHandle);\r | |
1910 | }\r | |
1911 | \r | |
1912 | /**\r | |
1913 | Starts a device controller or a bus controller.\r | |
1914 | \r | |
1915 | The Start() function is designed to be invoked from the EFI boot service ConnectController().\r | |
1916 | As a result, much of the error checking on the parameters to Start() has been moved into this\r | |
1917 | common boot service. It is legal to call Start() from other locations,\r | |
1918 | but the following calling restrictions must be followed, or the system behavior will not be deterministic.\r | |
1919 | 1. ControllerHandle must be a valid EFI_HANDLE.\r | |
1920 | 2. If RemainingDevicePath is not NULL, then it must be a pointer to a naturally aligned\r | |
1921 | EFI_DEVICE_PATH_PROTOCOL.\r | |
1922 | 3. Prior to calling Start(), the Supported() function for the driver specified by This must\r | |
1923 | have been called with the same calling parameters, and Supported() must have returned EFI_SUCCESS.\r | |
1924 | \r | |
1925 | @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.\r | |
1926 | @param[in] ControllerHandle The handle of the controller to start. This handle\r | |
1927 | must support a protocol interface that supplies\r | |
1928 | an I/O abstraction to the driver.\r | |
1929 | @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This\r | |
1930 | parameter is ignored by device drivers, and is optional for bus\r | |
1931 | drivers. For a bus driver, if this parameter is NULL, then handles\r | |
1932 | for all the children of Controller are created by this driver.\r | |
1933 | If this parameter is not NULL and the first Device Path Node is\r | |
1934 | not the End of Device Path Node, then only the handle for the\r | |
1935 | child device specified by the first Device Path Node of\r | |
1936 | RemainingDevicePath is created by this driver.\r | |
1937 | If the first Device Path Node of RemainingDevicePath is\r | |
1938 | the End of Device Path Node, no child handle is created by this\r | |
1939 | driver.\r | |
1940 | \r | |
1941 | @retval EFI_SUCCESS The device was started.\r | |
1942 | @retval EFI_DEVICE_ERROR The device could not be started due to a device error.Currently not implemented.\r | |
1943 | @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.\r | |
1944 | @retval Others The driver failded to start the device.\r | |
1945 | \r | |
1946 | **/\r | |
1947 | EFI_STATUS\r | |
1948 | EFIAPI\r | |
1949 | RedfishDiscoverDriverBindingStart (\r | |
1950 | IN EFI_DRIVER_BINDING_PROTOCOL *This,\r | |
1951 | IN EFI_HANDLE ControllerHandle,\r | |
1952 | IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL\r | |
1953 | )\r | |
1954 | {\r | |
1955 | return BuildupNetworkInterface (This, ControllerHandle);\r | |
1956 | }\r | |
1957 | \r | |
1958 | /**\r | |
1959 | Stops a device controller or a bus controller.\r | |
1960 | \r | |
1961 | The Stop() function is designed to be invoked from the EFI boot service DisconnectController().\r | |
1962 | As a result, much of the error checking on the parameters to Stop() has been moved\r | |
1963 | into this common boot service. It is legal to call Stop() from other locations,\r | |
1964 | but the following calling restrictions must be followed, or the system behavior will not be deterministic.\r | |
1965 | 1. ControllerHandle must be a valid EFI_HANDLE that was used on a previous call to this\r | |
1966 | same driver's Start() function.\r | |
1967 | 2. The first NumberOfChildren handles of ChildHandleBuffer must all be a valid\r | |
1968 | EFI_HANDLE. In addition, all of these handles must have been created in this driver's\r | |
1969 | Start() function, and the Start() function must have called OpenProtocol() on\r | |
1970 | ControllerHandle with an Attribute of EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER.\r | |
1971 | \r | |
1972 | @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.\r | |
1973 | @param[in] ControllerHandle A handle to the device being stopped. The handle must\r | |
1974 | support a bus specific I/O protocol for the driver\r | |
1975 | to use to stop the device.\r | |
1976 | @param[in] NumberOfChildren The number of child device handles in ChildHandleBuffer.\r | |
1977 | @param[in] ChildHandleBuffer An array of child handles to be freed. May be NULL\r | |
1978 | if NumberOfChildren is 0.\r | |
1979 | \r | |
1980 | @retval EFI_SUCCESS The device was stopped.\r | |
1981 | @retval EFI_DEVICE_ERROR The device could not be stopped due to a device error.\r | |
1982 | \r | |
1983 | **/\r | |
1984 | EFI_STATUS\r | |
1985 | EFIAPI\r | |
1986 | RedfishDiscoverDriverBindingStop (\r | |
1987 | IN EFI_DRIVER_BINDING_PROTOCOL *This,\r | |
1988 | IN EFI_HANDLE ControllerHandle,\r | |
1989 | IN UINTN NumberOfChildren,\r | |
1990 | IN EFI_HANDLE *ChildHandleBuffer OPTIONAL\r | |
1991 | )\r | |
1992 | {\r | |
1993 | return StopServiceOnNetworkInterface (This, ControllerHandle);\r | |
1994 | }\r | |
1995 | \r | |
39de741e | 1996 | EFI_DRIVER_BINDING_PROTOCOL gRedfishDiscoverDriverBinding = {\r |
7e7b729f AC |
1997 | RedfishDiscoverDriverBindingSupported,\r |
1998 | RedfishDiscoverDriverBindingStart,\r | |
1999 | RedfishDiscoverDriverBindingStop,\r | |
2000 | REDFISH_DISCOVER_VERSION,\r | |
2001 | NULL,\r | |
2002 | NULL\r | |
2003 | };\r | |
2004 | \r | |
2005 | /**\r | |
2006 | This is the declaration of an EFI image entry point.\r | |
2007 | \r | |
2008 | @param ImageHandle The firmware allocated handle for the UEFI image.\r | |
2009 | @param SystemTable A pointer to the EFI System Table.\r | |
2010 | \r | |
2011 | @retval EFI_SUCCESS The operation completed successfully.\r | |
2012 | @retval Others An unexpected error occurred.\r | |
2013 | **/\r | |
2014 | EFI_STATUS\r | |
2015 | EFIAPI\r | |
2016 | RedfishDiscoverEntryPoint (\r | |
2017 | IN EFI_HANDLE ImageHandle,\r | |
2018 | IN EFI_SYSTEM_TABLE *SystemTable\r | |
2019 | )\r | |
2020 | {\r | |
39de741e | 2021 | EFI_STATUS Status;\r |
7e7b729f AC |
2022 | \r |
2023 | Status = EFI_SUCCESS;\r | |
2024 | InitializeListHead (&mRedfishDiscoverList);\r | |
2025 | InitializeListHead (&mRedfishInstanceList);\r | |
2026 | InitializeListHead (&mEfiRedfishDiscoverNetworkInterface);\r | |
2027 | InitializeListHead (&mEfiRedfishDiscoverRestExInstance);\r | |
2028 | //\r | |
2029 | // Install binding protoocl to obtain UDP and REST EX protocol.\r | |
2030 | //\r | |
2031 | Status = EfiLibInstallDriverBindingComponentName2 (\r | |
2032 | ImageHandle,\r | |
2033 | SystemTable,\r | |
2034 | &gRedfishDiscoverDriverBinding,\r | |
2035 | ImageHandle,\r | |
2036 | &gRedfishDiscoverComponentName,\r | |
2037 | &gRedfishDiscoverComponentName2\r | |
2038 | );\r | |
2039 | return Status;\r | |
2040 | }\r | |
2041 | \r | |
2042 | /**\r | |
2043 | This is the unload handle for Redfish discover module.\r | |
2044 | \r | |
2045 | Disconnect the driver specified by ImageHandle from all the devices in the handle database.\r | |
2046 | Uninstall all the protocols installed in the driver entry point.\r | |
2047 | \r | |
2048 | @param[in] ImageHandle The drivers' driver image.\r | |
2049 | \r | |
2050 | @retval EFI_SUCCESS The image is unloaded.\r | |
2051 | @retval Others Failed to unload the image.\r | |
2052 | \r | |
2053 | **/\r | |
2054 | EFI_STATUS\r | |
2055 | EFIAPI\r | |
2056 | RedfishDiscoverUnload (\r | |
39de741e | 2057 | IN EFI_HANDLE ImageHandle\r |
7e7b729f AC |
2058 | )\r |
2059 | {\r | |
39de741e MK |
2060 | EFI_STATUS Status;\r |
2061 | EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *ThisNetworkInterface;\r | |
7e7b729f AC |
2062 | \r |
2063 | Status = EFI_SUCCESS;\r | |
2064 | // Destroy all network interfaces found by EFI Redfish Discover driver and\r | |
2065 | // stop services created for Redfish Discover.\r | |
2066 | \r | |
2067 | while (!IsListEmpty (&mEfiRedfishDiscoverNetworkInterface)) {\r | |
2068 | ThisNetworkInterface = (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *)GetFirstNode (&mEfiRedfishDiscoverNetworkInterface);\r | |
2069 | StopServiceOnNetworkInterface (&gRedfishDiscoverDriverBinding, ThisNetworkInterface->NetworkInterfaceProtocolInfo.ProtocolControllerHandle);\r | |
39de741e MK |
2070 | }\r |
2071 | \r | |
7e7b729f AC |
2072 | return Status;\r |
2073 | }\r |