!if $(REDFISH_ENABLE) == TRUE\r
INF RedfishPkg/RestJsonStructureDxe/RestJsonStructureDxe.inf\r
INF RedfishPkg/RedfishHostInterfaceDxe/RedfishHostInterfaceDxe.inf\r
+ INF RedfishPkg/RedfishRestExDxe/RedfishRestExDxe.inf\r
!endif\r
!if $(REDFISH_ENABLE) == TRUE\r
RedfishPkg/RestJsonStructureDxe/RestJsonStructureDxe.inf\r
RedfishPkg/RedfishHostInterfaceDxe/RedfishHostInterfaceDxe.inf\r
+ RedfishPkg/RedfishRestExDxe/RedfishRestExDxe.inf\r
!endif\r
DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf\r
PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf\r
RedfishPlatformHostInterfaceLib|RedfishPkg/Library/PlatformHostInterfaceLibNull/PlatformHostInterfaceLibNull.inf\r
+ HttpLib|NetworkPkg/Library/DxeHttpLib/DxeHttpLib.inf\r
+ HttpIoLib|NetworkPkg/Library/DxeHttpIoLib/DxeHttpIoLib.inf\r
+ NetLib|NetworkPkg/Library/DxeNetLib/DxeNetLib.inf\r
+ DpcLib|NetworkPkg/Library/DxeDpcLib/DxeDpcLib.inf\r
\r
[LibraryClasses.ARM, LibraryClasses.AARCH64]\r
#\r
--- /dev/null
+/** @file\r
+ Implementation of EFI_COMPONENT_NAME_PROTOCOL and EFI_COMPONENT_NAME2_PROTOCOL\r
+ protocol.\r
+\r
+ Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>\r
+ (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>\r
+\r
+ SPDX-License-Identifier: BSD-2-Clause-Patent\r
+\r
+**/\r
+#include <Uefi.h>\r
+\r
+#include <Library/UefiLib.h>\r
+\r
+#include <Protocol/ComponentName.h>\r
+#include <Protocol/ComponentName2.h>\r
+\r
+//\r
+// EFI Component Name Functions\r
+//\r
+/**\r
+ Retrieves a Unicode string that is the user-readable name of the EFI Driver.\r
+\r
+ @param[in] This A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.\r
+ @param[in] Language A pointer to a three-character ISO 639-2 language identifier.\r
+ This is the language of the driver name that that the caller\r
+ is requesting, and it must match one of the languages specified\r
+ in SupportedLanguages. The number of languages supported by a\r
+ driver is up to the driver writer.\r
+ @param[out] DriverName A pointer to the Unicode string to return. This Unicode string\r
+ is the name of the driver specified by This in the language\r
+ specified by Language.\r
+\r
+ @retval EFI_SUCCESS The Unicode string for the Driver specified by This\r
+ and the language specified by Language was returned\r
+ in DriverName.\r
+ @retval EFI_INVALID_PARAMETER Language is NULL.\r
+ @retval EFI_INVALID_PARAMETER DriverName is NULL.\r
+ @retval EFI_UNSUPPORTED The driver specified by This does not support the\r
+ language specified by Language.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+RedfishRestExComponentNameGetDriverName (\r
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,\r
+ IN CHAR8 *Language,\r
+ OUT CHAR16 **DriverName\r
+ );\r
+\r
+/**\r
+ Retrieves a Unicode string that is the user readable name of the controller\r
+ that is being managed by an EFI Driver.\r
+\r
+ @param[in] This A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.\r
+ @param[in] ControllerHandle The handle of a controller that the driver specified by\r
+ This is managing. This handle specifies the controller\r
+ whose name is to be returned.\r
+ @param[in] ChildHandle The handle of the child controller to retrieve the name\r
+ of. This is an optional parameter that may be NULL. It\r
+ will be NULL for device drivers. It will also be NULL\r
+ for a bus drivers that wish to retrieve the name of the\r
+ bus controller. It will not be NULL for a bus driver\r
+ that wishes to retrieve the name of a child controller.\r
+ @param[in] Language A pointer to a three character ISO 639-2 language\r
+ identifier. This is the language of the controller name\r
+ that the caller is requesting, and it must match one\r
+ of the languages specified in SupportedLanguages. The\r
+ number of languages supported by a driver is up to the\r
+ driver writer.\r
+ @param[out] ControllerName A pointer to the Unicode string to return. This Unicode\r
+ string is the name of the controller specified by\r
+ ControllerHandle and ChildHandle in the language specified\r
+ by Language, from the point of view of the driver specified\r
+ by This.\r
+\r
+ @retval EFI_SUCCESS The Unicode string for the user-readable name in the\r
+ language specified by Language for the driver\r
+ specified by This was returned in DriverName.\r
+ @retval EFI_INVALID_PARAMETER ControllerHandle is NULL.\r
+ @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid EFI_HANDLE.\r
+ @retval EFI_INVALID_PARAMETER Language is NULL.\r
+ @retval EFI_INVALID_PARAMETER ControllerName is NULL.\r
+ @retval EFI_UNSUPPORTED The driver specified by This is not currently managing\r
+ the controller specified by ControllerHandle and\r
+ ChildHandle.\r
+ @retval EFI_UNSUPPORTED The driver specified by This does not support the\r
+ language specified by Language.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+RedfishRestExComponentNameGetControllerName (\r
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,\r
+ IN EFI_HANDLE ControllerHandle,\r
+ IN EFI_HANDLE ChildHandle OPTIONAL,\r
+ IN CHAR8 *Language,\r
+ OUT CHAR16 **ControllerName\r
+ );\r
+\r
+///\r
+/// Component Name Protocol instance\r
+///\r
+GLOBAL_REMOVE_IF_UNREFERENCED\r
+EFI_COMPONENT_NAME_PROTOCOL gRedfishRestExComponentName = {\r
+ RedfishRestExComponentNameGetDriverName,\r
+ RedfishRestExComponentNameGetControllerName,\r
+ "eng"\r
+};\r
+\r
+///\r
+/// Component Name 2 Protocol instance\r
+///\r
+GLOBAL_REMOVE_IF_UNREFERENCED\r
+EFI_COMPONENT_NAME2_PROTOCOL gRedfishRestExComponentName2 = {\r
+ (EFI_COMPONENT_NAME2_GET_DRIVER_NAME) RedfishRestExComponentNameGetDriverName,\r
+ (EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME) RedfishRestExComponentNameGetControllerName,\r
+ "en"\r
+};\r
+\r
+///\r
+/// Table of driver names\r
+///\r
+GLOBAL_REMOVE_IF_UNREFERENCED\r
+EFI_UNICODE_STRING_TABLE mRedfishRestExDriverNameTable[] = {\r
+ { "eng;en", (CHAR16 *)L"Redfish RestEx Network Service Driver" },\r
+ { NULL, NULL }\r
+};\r
+\r
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE *gRedfishRestExControllerNameTable = NULL;\r
+\r
+/**\r
+ Retrieves a Unicode string that is the user-readable name of the EFI Driver.\r
+\r
+ @param[in] This A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.\r
+ @param[in] Language A pointer to a three-character ISO 639-2 language identifier.\r
+ This is the language of the driver name that that the caller\r
+ is requesting, and it must match one of the languages specified\r
+ in SupportedLanguages. The number of languages supported by a\r
+ driver is up to the driver writer.\r
+ @param[out] DriverName A pointer to the Unicode string to return. This Unicode string\r
+ is the name of the driver specified by This in the language\r
+ specified by Language.\r
+\r
+ @retval EFI_SUCCESS The Unicode string for the Driver specified by This\r
+ and the language specified by Language was returned\r
+ in DriverName.\r
+ @retval EFI_INVALID_PARAMETER Language is NULL.\r
+ @retval EFI_INVALID_PARAMETER DriverName is NULL.\r
+ @retval EFI_UNSUPPORTED The driver specified by This does not support the\r
+ language specified by Language.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+RedfishRestExComponentNameGetDriverName (\r
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,\r
+ IN CHAR8 *Language,\r
+ OUT CHAR16 **DriverName\r
+ )\r
+{\r
+ return LookupUnicodeString2 (\r
+ Language,\r
+ This->SupportedLanguages,\r
+ mRedfishRestExDriverNameTable,\r
+ DriverName,\r
+ (BOOLEAN)(This == &gRedfishRestExComponentName)\r
+ );\r
+}\r
+\r
+/**\r
+ Retrieves a Unicode string that is the user readable name of the controller\r
+ that is being managed by an EFI Driver.\r
+\r
+ @param[in] This A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.\r
+ @param[in] ControllerHandle The handle of a controller that the driver specified by\r
+ This is managing. This handle specifies the controller\r
+ whose name is to be returned.\r
+ @param[in] ChildHandle The handle of the child controller to retrieve the name\r
+ of. This is an optional parameter that may be NULL. It\r
+ will be NULL for device drivers. It will also be NULL\r
+ for a bus drivers that wish to retrieve the name of the\r
+ bus controller. It will not be NULL for a bus driver\r
+ that wishes to retrieve the name of a child controller.\r
+ @param[in] Language A pointer to a three character ISO 639-2 language\r
+ identifier. This is the language of the controller name\r
+ that the caller is requesting, and it must match one\r
+ of the languages specified in SupportedLanguages. The\r
+ number of languages supported by a driver is up to the\r
+ driver writer.\r
+ @param[out] ControllerName A pointer to the Unicode string to return. This Unicode\r
+ string is the name of the controller specified by\r
+ ControllerHandle and ChildHandle in the language specified\r
+ by Language, from the point of view of the driver specified\r
+ by This.\r
+\r
+ @retval EFI_SUCCESS The Unicode string for the user-readable name in the\r
+ language specified by Language for the driver\r
+ specified by This was returned in DriverName.\r
+ @retval EFI_INVALID_PARAMETER ControllerHandle is NULL.\r
+ @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid EFI_HANDLE.\r
+ @retval EFI_INVALID_PARAMETER Language is NULL.\r
+ @retval EFI_INVALID_PARAMETER ControllerName is NULL.\r
+ @retval EFI_UNSUPPORTED The driver specified by This is not currently managing\r
+ the controller specified by ControllerHandle and\r
+ ChildHandle.\r
+ @retval EFI_UNSUPPORTED The driver specified by This does not support the\r
+ language specified by Language.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+RedfishRestExComponentNameGetControllerName (\r
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,\r
+ IN EFI_HANDLE ControllerHandle,\r
+ IN EFI_HANDLE ChildHandle OPTIONAL,\r
+ IN CHAR8 *Language,\r
+ OUT CHAR16 **ControllerName\r
+ )\r
+{\r
+ return EFI_UNSUPPORTED;\r
+}\r
--- /dev/null
+/** @file\r
+ The driver binding and service binding protocol for Redfish RestExDxe driver.\r
+\r
+ Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>\r
+ (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>\r
+\r
+ SPDX-License-Identifier: BSD-2-Clause-Patent\r
+\r
+**/\r
+\r
+#include <Uefi.h>\r
+#include "RedfishRestExDriver.h"\r
+\r
+EFI_DRIVER_BINDING_PROTOCOL gRedfishRestExDriverBinding = {\r
+ RedfishRestExDriverBindingSupported,\r
+ RedfishRestExDriverBindingStart,\r
+ RedfishRestExDriverBindingStop,\r
+ REDFISH_RESTEX_DRIVER_VERSION,\r
+ NULL,\r
+ NULL\r
+};\r
+\r
+EFI_SERVICE_BINDING_PROTOCOL mRedfishRestExServiceBinding = {\r
+ RedfishRestExServiceBindingCreateChild,\r
+ RedfishRestExServiceBindingDestroyChild\r
+};\r
+\r
+/**\r
+ Callback function which provided by user to remove one node in NetDestroyLinkList process.\r
+\r
+ @param[in] Entry The entry to be removed.\r
+ @param[in] Context Pointer to the callback context corresponds to the Context in NetDestroyLinkList.\r
+\r
+ @retval EFI_SUCCESS The entry has been removed successfully.\r
+ @retval Others Fail to remove the entry.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+RestExDestroyChildEntryInHandleBuffer (\r
+ IN LIST_ENTRY *Entry,\r
+ IN VOID *Context\r
+ )\r
+{\r
+ RESTEX_INSTANCE *Instance;\r
+ EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;\r
+ UINTN NumberOfChildren;\r
+ EFI_HANDLE *ChildHandleBuffer;\r
+\r
+ if (Entry == NULL || Context == NULL) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ Instance = NET_LIST_USER_STRUCT_S (Entry, RESTEX_INSTANCE, Link, RESTEX_INSTANCE_SIGNATURE);\r
+ ServiceBinding = ((RESTEX_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *) Context)->ServiceBinding;\r
+ NumberOfChildren = ((RESTEX_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *) Context)->NumberOfChildren;\r
+ ChildHandleBuffer = ((RESTEX_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *) Context)->ChildHandleBuffer;\r
+\r
+ if (!NetIsInHandleBuffer (Instance->ChildHandle, NumberOfChildren, ChildHandleBuffer)) {\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ return ServiceBinding->DestroyChild (ServiceBinding, Instance->ChildHandle);\r
+}\r
+\r
+/**\r
+ Destroy the RestEx instance and recycle the resources.\r
+\r
+ @param[in] Instance The pointer to the RestEx instance.\r
+\r
+**/\r
+VOID\r
+RestExDestroyInstance (\r
+ IN RESTEX_INSTANCE *Instance\r
+ )\r
+{\r
+ HttpIoDestroyIo (&(Instance->HttpIo));\r
+\r
+ FreePool (Instance);\r
+}\r
+\r
+/**\r
+ Create the RestEx instance and initialize it.\r
+\r
+ @param[in] Service The pointer to the RestEx service.\r
+ @param[out] Instance The pointer to the RestEx instance.\r
+\r
+ @retval EFI_OUT_OF_RESOURCES Failed to allocate resources.\r
+ @retval EFI_SUCCESS The RestEx instance is created.\r
+\r
+**/\r
+EFI_STATUS\r
+RestExCreateInstance (\r
+ IN RESTEX_SERVICE *Service,\r
+ OUT RESTEX_INSTANCE **Instance\r
+ )\r
+{\r
+ RESTEX_INSTANCE *RestExIns;\r
+ EFI_STATUS Status;\r
+\r
+ *Instance = NULL;\r
+ Status = EFI_SUCCESS;\r
+\r
+ RestExIns = AllocateZeroPool (sizeof (RESTEX_INSTANCE));\r
+ if (RestExIns == NULL) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+\r
+ RestExIns->Signature = RESTEX_INSTANCE_SIGNATURE;\r
+ InitializeListHead (&RestExIns->Link);\r
+ RestExIns->InDestroy = FALSE;\r
+ RestExIns->Service = Service;\r
+\r
+ CopyMem (&RestExIns->RestEx, &mRedfishRestExProtocol, sizeof (RestExIns->RestEx));\r
+\r
+ //\r
+ // Create a HTTP_IO to access the HTTP service.\r
+ //\r
+ Status = HttpIoCreateIo (\r
+ RestExIns->Service->ImageHandle,\r
+ RestExIns->Service->ControllerHandle,\r
+ IP_VERSION_4,\r
+ NULL,\r
+ NULL,\r
+ NULL,\r
+ &(RestExIns->HttpIo)\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ FreePool (RestExIns);\r
+ return Status;\r
+ }\r
+\r
+ *Instance = RestExIns;\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+ Release all the resource used the RestEx service binding instance.\r
+\r
+ @param[in] RestExSb The RestEx service binding instance.\r
+\r
+**/\r
+VOID\r
+RestExDestroyService (\r
+ IN RESTEX_SERVICE *RestExSb\r
+ )\r
+{\r
+ if (RestExSb->HttpChildHandle != NULL) {\r
+ gBS->CloseProtocol (\r
+ RestExSb->HttpChildHandle,\r
+ &gEfiHttpProtocolGuid,\r
+ RestExSb->ImageHandle,\r
+ RestExSb->ControllerHandle\r
+ );\r
+\r
+ NetLibDestroyServiceChild (\r
+ RestExSb->ControllerHandle,\r
+ RestExSb->ImageHandle,\r
+ &gEfiHttpServiceBindingProtocolGuid,\r
+ RestExSb->HttpChildHandle\r
+ );\r
+\r
+ RestExSb->HttpChildHandle = NULL;\r
+ }\r
+\r
+ gBS->UninstallProtocolInterface (\r
+ RestExSb->ControllerHandle,\r
+ &gEfiCallerIdGuid,\r
+ &RestExSb->Id\r
+ );\r
+\r
+ FreePool (RestExSb);\r
+}\r
+\r
+/**\r
+ Check the NIC controller handle represents an in-band or out-of-band Redfish host\r
+ interface device. If not in-band, treat it as out-of-band interface device.\r
+\r
+ @param[in] Controller The NIC controller handle needs to be checked.\r
+\r
+ @return EFI_REST_EX_SERVICE_ACCESS_MODE of the device.\r
+\r
+**/\r
+EFI_REST_EX_SERVICE_ACCESS_MODE\r
+RestExServiceAccessMode (\r
+ IN EFI_HANDLE Controller\r
+ )\r
+{\r
+ //\r
+ // This is EFI REST EX driver instance to connect\r
+ // to Redfish service using HTTP in out of band.\r
+ //\r
+ if (FixedPcdGetBool (PcdRedfishRestExServiceAccessModeInBand)) {\r
+ return EfiRestExServiceInBandAccess;\r
+ } else {\r
+ return EfiRestExServiceOutOfBandAccess;\r
+ }\r
+}\r
+\r
+/**\r
+ Create then initialize a RestEx service binding instance.\r
+\r
+ @param[in] Controller The controller to install the RestEx service\r
+ binding on.\r
+ @param[in] Image The driver binding image of the RestEx driver.\r
+ @param[out] Service The variable to receive the created service\r
+ binding instance.\r
+\r
+ @retval EFI_OUT_OF_RESOURCES Failed to allocate resource to create the instance.\r
+ @retval EFI_SUCCESS The service instance is created for the controller.\r
+\r
+**/\r
+EFI_STATUS\r
+RestExCreateService (\r
+ IN EFI_HANDLE Controller,\r
+ IN EFI_HANDLE Image,\r
+ OUT RESTEX_SERVICE **Service\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ RESTEX_SERVICE *RestExSb;\r
+\r
+ Status = EFI_SUCCESS;\r
+ RestExSb = NULL;\r
+\r
+ *Service = NULL;\r
+\r
+ RestExSb = AllocateZeroPool (sizeof (RESTEX_SERVICE));\r
+ if (RestExSb == NULL) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+\r
+ RestExSb->Signature = RESTEX_SERVICE_SIGNATURE;\r
+\r
+ RestExSb->ServiceBinding = mRedfishRestExServiceBinding;\r
+\r
+ RestExSb->RestExChildrenNum = 0;\r
+ InitializeListHead (&RestExSb->RestExChildrenList);\r
+\r
+ RestExSb->ControllerHandle = Controller;\r
+ RestExSb->ImageHandle = Image;\r
+\r
+ RestExSb->RestExServiceInfo.EfiRestExServiceInfoV10.EfiRestExServiceInfoHeader.Length = sizeof (EFI_REST_EX_SERVICE_INFO);\r
+ RestExSb->RestExServiceInfo.EfiRestExServiceInfoV10.EfiRestExServiceInfoHeader.RestServiceInfoVer.Major = 1;\r
+ RestExSb->RestExServiceInfo.EfiRestExServiceInfoV10.EfiRestExServiceInfoHeader.RestServiceInfoVer.Minor = 0;\r
+ RestExSb->RestExServiceInfo.EfiRestExServiceInfoV10.RestServiceType = EfiRestExServiceRedfish;\r
+ RestExSb->RestExServiceInfo.EfiRestExServiceInfoV10.RestServiceAccessMode = RestExServiceAccessMode (Controller);\r
+ RestExSb->RestExServiceInfo.EfiRestExServiceInfoV10.RestExConfigType = EfiRestExConfigHttp;\r
+ RestExSb->RestExServiceInfo.EfiRestExServiceInfoV10.RestExConfigDataLength = sizeof (EFI_REST_EX_HTTP_CONFIG_DATA);\r
+\r
+ Status = gBS->InstallProtocolInterface (\r
+ &Controller,\r
+ &gEfiCallerIdGuid,\r
+ EFI_NATIVE_INTERFACE,\r
+ &RestExSb->Id\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ FreePool (RestExSb);\r
+ RestExSb = NULL;\r
+ }\r
+\r
+ *Service = RestExSb;\r
+ return Status;\r
+}\r
+\r
+/**\r
+ This is the declaration of an EFI image entry point. This entry point is\r
+ the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers including\r
+ both device drivers and bus drivers.\r
+\r
+ @param[in] ImageHandle The firmware allocated handle for the UEFI image.\r
+ @param[in] SystemTable A pointer to the EFI System Table.\r
+\r
+ @retval EFI_SUCCESS The operation completed successfully.\r
+ @retval Others An unexpected error occurred.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+RedfishRestExDriverEntryPoint (\r
+ IN EFI_HANDLE ImageHandle,\r
+ IN EFI_SYSTEM_TABLE *SystemTable\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+\r
+ Status = EFI_SUCCESS;\r
+\r
+ //\r
+ // Install the RestEx Driver Binding Protocol.\r
+ //\r
+ Status = EfiLibInstallDriverBindingComponentName2 (\r
+ ImageHandle,\r
+ SystemTable,\r
+ &gRedfishRestExDriverBinding,\r
+ ImageHandle,\r
+ &gRedfishRestExComponentName,\r
+ &gRedfishRestExComponentName2\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ return Status;\r
+}\r
+\r
+/**\r
+ Tests to see if this driver supports a given controller. If a child device is provided,\r
+ it further tests to see if this driver supports creating a handle for the specified child device.\r
+\r
+ This function checks to see if the driver specified by This supports the device specified by\r
+ ControllerHandle. Drivers will typically use the device path attached to\r
+ ControllerHandle and/or the services from the bus I/O abstraction attached to\r
+ ControllerHandle to determine if the driver supports ControllerHandle. This function\r
+ may be called many times during platform initialization. In order to reduce boot times, the tests\r
+ performed by this function must be very small, and take as little time as possible to execute. This\r
+ function must not change the state of any hardware devices, and this function must be aware that the\r
+ device specified by ControllerHandle may already be managed by the same driver or a\r
+ different driver. This function must match its calls to AllocatePages() with FreePages(),\r
+ AllocatePool() with FreePool(), and OpenProtocol() with CloseProtocol().\r
+ Because ControllerHandle may have been previously started by the same driver, if a protocol is\r
+ already in the opened state, then it must not be closed with CloseProtocol(). This is required\r
+ to guarantee the state of ControllerHandle is not modified by this function.\r
+\r
+ @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.\r
+ @param[in] ControllerHandle The handle of the controller to test. This handle\r
+ must support a protocol interface that supplies\r
+ an I/O abstraction to the driver.\r
+ @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This\r
+ parameter is ignored by device drivers, and is optional for bus\r
+ drivers. For bus drivers, if this parameter is not NULL, then\r
+ the bus driver must determine if the bus controller specified\r
+ by ControllerHandle and the child controller specified\r
+ by RemainingDevicePath are both supported by this\r
+ bus driver.\r
+\r
+ @retval EFI_SUCCESS The device specified by ControllerHandle and\r
+ RemainingDevicePath is supported by the driver specified by This.\r
+ @retval EFI_ALREADY_STARTED The device specified by ControllerHandle and\r
+ RemainingDevicePath is already being managed by the driver\r
+ specified by This.\r
+ @retval EFI_ACCESS_DENIED The device specified by ControllerHandle and\r
+ RemainingDevicePath is already being managed by a different\r
+ driver or an application that requires exclusive access.\r
+ Currently not implemented.\r
+ @retval EFI_UNSUPPORTED The device specified by ControllerHandle and\r
+ RemainingDevicePath is not supported by the driver specified by This.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+RedfishRestExDriverBindingSupported (\r
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
+ IN EFI_HANDLE ControllerHandle,\r
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL\r
+ )\r
+{\r
+\r
+ //\r
+ // Test for the HttpServiceBinding Protocol.\r
+ //\r
+ return gBS->OpenProtocol (\r
+ ControllerHandle,\r
+ &gEfiHttpServiceBindingProtocolGuid,\r
+ NULL,\r
+ This->DriverBindingHandle,\r
+ ControllerHandle,\r
+ EFI_OPEN_PROTOCOL_TEST_PROTOCOL\r
+ );\r
+\r
+}\r
+\r
+/**\r
+ Starts a device controller or a bus controller.\r
+\r
+ The Start() function is designed to be invoked from the EFI boot service ConnectController().\r
+ As a result, much of the error checking on the parameters to Start() has been moved into this\r
+ common boot service. It is legal to call Start() from other locations,\r
+ but the following calling restrictions must be followed, or the system behavior will not be deterministic.\r
+ 1. ControllerHandle must be a valid EFI_HANDLE.\r
+ 2. If RemainingDevicePath is not NULL, then it must be a pointer to a naturally aligned\r
+ EFI_DEVICE_PATH_PROTOCOL.\r
+ 3. Prior to calling Start(), the Supported() function for the driver specified by This must\r
+ have been called with the same calling parameters, and Supported() must have returned EFI_SUCCESS.\r
+\r
+ @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.\r
+ @param[in] ControllerHandle The handle of the controller to start. This handle\r
+ must support a protocol interface that supplies\r
+ an I/O abstraction to the driver.\r
+ @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This\r
+ parameter is ignored by device drivers, and is optional for bus\r
+ drivers. For a bus driver, if this parameter is NULL, then handles\r
+ for all the children of Controller are created by this driver.\r
+ If this parameter is not NULL and the first Device Path Node is\r
+ not the End of Device Path Node, then only the handle for the\r
+ child device specified by the first Device Path Node of\r
+ RemainingDevicePath is created by this driver.\r
+ If the first Device Path Node of RemainingDevicePath is\r
+ the End of Device Path Node, no child handle is created by this\r
+ driver.\r
+\r
+ @retval EFI_SUCCESS The device was started.\r
+ @retval EFI_DEVICE_ERROR The device could not be started due to a device error.Currently not implemented.\r
+ @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.\r
+ @retval Others The driver failded to start the device.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+RedfishRestExDriverBindingStart (\r
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
+ IN EFI_HANDLE ControllerHandle,\r
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL\r
+ )\r
+{\r
+ RESTEX_SERVICE *RestExSb;\r
+ EFI_STATUS Status;\r
+ UINT32 *Id;\r
+ VOID *Interface;\r
+\r
+ Status = gBS->OpenProtocol (\r
+ ControllerHandle,\r
+ &gEfiCallerIdGuid,\r
+ (VOID **) &Id,\r
+ This->DriverBindingHandle,\r
+ ControllerHandle,\r
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+ );\r
+ if (!EFI_ERROR (Status)) {\r
+ return EFI_ALREADY_STARTED;\r
+ }\r
+\r
+ Status = RestExCreateService (ControllerHandle, This->DriverBindingHandle, &RestExSb);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ ASSERT (RestExSb != NULL);\r
+\r
+ //\r
+ // Create a Http child instance, but do not configure it.\r
+ // This will establish the parent-child relationship.\r
+ //\r
+ Status = NetLibCreateServiceChild (\r
+ ControllerHandle,\r
+ This->DriverBindingHandle,\r
+ &gEfiHttpServiceBindingProtocolGuid,\r
+ &RestExSb->HttpChildHandle\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ goto ON_ERROR;\r
+ }\r
+\r
+ Status = gBS->OpenProtocol (\r
+ RestExSb->HttpChildHandle,\r
+ &gEfiHttpProtocolGuid,\r
+ &Interface,\r
+ This->DriverBindingHandle,\r
+ ControllerHandle,\r
+ EFI_OPEN_PROTOCOL_BY_DRIVER\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ goto ON_ERROR;\r
+ }\r
+\r
+ //\r
+ // Install the RestEx ServiceBinding Protocol onto ControllerHandle.\r
+ //\r
+ Status = gBS->InstallMultipleProtocolInterfaces (\r
+ &ControllerHandle,\r
+ &gEfiRestExServiceBindingProtocolGuid,\r
+ &RestExSb->ServiceBinding,\r
+ NULL\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ goto ON_ERROR;\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+\r
+ON_ERROR:\r
+ RestExDestroyService (RestExSb);\r
+\r
+ return Status;\r
+}\r
+\r
+/**\r
+ Stops a device controller or a bus controller.\r
+\r
+ The Stop() function is designed to be invoked from the EFI boot service DisconnectController().\r
+ As a result, much of the error checking on the parameters to Stop() has been moved\r
+ into this common boot service. It is legal to call Stop() from other locations,\r
+ but the following calling restrictions must be followed, or the system behavior will not be deterministic.\r
+ 1. ControllerHandle must be a valid EFI_HANDLE that was used on a previous call to this\r
+ same driver's Start() function.\r
+ 2. The first NumberOfChildren handles of ChildHandleBuffer must all be a valid\r
+ EFI_HANDLE. In addition, all of these handles must have been created in this driver's\r
+ Start() function, and the Start() function must have called OpenProtocol() on\r
+ ControllerHandle with an Attribute of EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER.\r
+\r
+ @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.\r
+ @param[in] ControllerHandle A handle to the device being stopped. The handle must\r
+ support a bus specific I/O protocol for the driver\r
+ to use to stop the device.\r
+ @param[in] NumberOfChildren The number of child device handles in ChildHandleBuffer.\r
+ @param[in] ChildHandleBuffer An array of child handles to be freed. May be NULL\r
+ if NumberOfChildren is 0.\r
+\r
+ @retval EFI_SUCCESS The device was stopped.\r
+ @retval EFI_DEVICE_ERROR The device could not be stopped due to a device error.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+RedfishRestExDriverBindingStop (\r
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
+ IN EFI_HANDLE ControllerHandle,\r
+ IN UINTN NumberOfChildren,\r
+ IN EFI_HANDLE *ChildHandleBuffer OPTIONAL\r
+ )\r
+{\r
+ EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;\r
+ RESTEX_SERVICE *RestExSb;\r
+ EFI_HANDLE NicHandle;\r
+ EFI_STATUS Status;\r
+ LIST_ENTRY *List;\r
+ RESTEX_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT Context;\r
+\r
+ //\r
+ // RestEx driver opens HTTP child, So, Controller is a HTTP\r
+ // child handle. Locate the Nic handle first. Then get the\r
+ // RestEx private data back.\r
+ //\r
+ NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiHttpProtocolGuid);\r
+ if (NicHandle == NULL) {\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ Status = gBS->OpenProtocol (\r
+ NicHandle,\r
+ &gEfiRestExServiceBindingProtocolGuid,\r
+ (VOID **) &ServiceBinding,\r
+ This->DriverBindingHandle,\r
+ NicHandle,\r
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
+\r
+ RestExSb = RESTEX_SERVICE_FROM_THIS (ServiceBinding);\r
+\r
+ if (!IsListEmpty (&RestExSb->RestExChildrenList)) {\r
+ //\r
+ // Destroy the RestEx child instance in ChildHandleBuffer.\r
+ //\r
+ List = &RestExSb->RestExChildrenList;\r
+ Context.ServiceBinding = ServiceBinding;\r
+ Context.NumberOfChildren = NumberOfChildren;\r
+ Context.ChildHandleBuffer = ChildHandleBuffer;\r
+ Status = NetDestroyLinkList (\r
+ List,\r
+ RestExDestroyChildEntryInHandleBuffer,\r
+ &Context,\r
+ NULL\r
+ );\r
+ }\r
+\r
+ if (NumberOfChildren == 0 && IsListEmpty (&RestExSb->RestExChildrenList)) {\r
+ gBS->UninstallProtocolInterface (\r
+ NicHandle,\r
+ &gEfiRestExServiceBindingProtocolGuid,\r
+ ServiceBinding\r
+ );\r
+\r
+ RestExDestroyService (RestExSb);\r
+\r
+ if (gRedfishRestExControllerNameTable != NULL) {\r
+ FreeUnicodeStringTable (gRedfishRestExControllerNameTable);\r
+ gRedfishRestExControllerNameTable = NULL;\r
+ }\r
+\r
+ Status = EFI_SUCCESS;\r
+ }\r
+\r
+ return Status;\r
+}\r
+\r
+/**\r
+ Creates a child handle and installs a protocol.\r
+\r
+ The CreateChild() function installs a protocol on ChildHandle.\r
+ If ChildHandle is a pointer to NULL, then a new handle is created and returned in ChildHandle.\r
+ If ChildHandle is not a pointer to NULL, then the protocol installs on the existing ChildHandle.\r
+\r
+ @param[in] This Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance.\r
+ @param[in] ChildHandle Pointer to the handle of the child to create. If it is NULL,\r
+ then a new handle is created. If it is a pointer to an existing UEFI handle,\r
+ then the protocol is added to the existing UEFI handle.\r
+\r
+ @retval EFI_SUCCES The protocol was added to ChildHandle.\r
+ @retval EFI_INVALID_PARAMETER ChildHandle is NULL.\r
+ @retval EFI_OUT_OF_RESOURCES There are not enough resources available to create\r
+ the child\r
+ @retval other The child handle was not created\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+RedfishRestExServiceBindingCreateChild (\r
+ IN EFI_SERVICE_BINDING_PROTOCOL *This,\r
+ IN EFI_HANDLE *ChildHandle\r
+ )\r
+{\r
+ RESTEX_SERVICE *RestExSb;\r
+ RESTEX_INSTANCE *Instance;\r
+ EFI_STATUS Status;\r
+ EFI_TPL OldTpl;\r
+ VOID *Http;\r
+\r
+ if ((This == NULL) || (ChildHandle == NULL)) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ RestExSb = RESTEX_SERVICE_FROM_THIS (This);\r
+\r
+ Status = RestExCreateInstance (RestExSb, &Instance);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+ ASSERT (Instance != NULL);\r
+\r
+ //\r
+ // Install the RestEx protocol onto ChildHandle\r
+ //\r
+ Status = gBS->InstallMultipleProtocolInterfaces (\r
+ ChildHandle,\r
+ &gEfiRestExProtocolGuid,\r
+ &Instance->RestEx,\r
+ NULL\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ goto ON_ERROR;\r
+ }\r
+\r
+ Instance->ChildHandle = *ChildHandle;\r
+\r
+ //\r
+ // Open the Http protocol BY_CHILD.\r
+ //\r
+ Status = gBS->OpenProtocol (\r
+ RestExSb->HttpChildHandle,\r
+ &gEfiHttpProtocolGuid,\r
+ (VOID **) &Http,\r
+ gRedfishRestExDriverBinding.DriverBindingHandle,\r
+ Instance->ChildHandle,\r
+ EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ gBS->UninstallMultipleProtocolInterfaces (\r
+ Instance->ChildHandle,\r
+ &gEfiRestExProtocolGuid,\r
+ &Instance->RestEx,\r
+ NULL\r
+ );\r
+\r
+ goto ON_ERROR;\r
+ }\r
+\r
+ //\r
+ // Open the Http protocol by child.\r
+ //\r
+ Status = gBS->OpenProtocol (\r
+ Instance->HttpIo.Handle,\r
+ &gEfiHttpProtocolGuid,\r
+ (VOID **) &Http,\r
+ gRedfishRestExDriverBinding.DriverBindingHandle,\r
+ Instance->ChildHandle,\r
+ EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ //\r
+ // Close the Http protocol.\r
+ //\r
+ gBS->CloseProtocol (\r
+ RestExSb->HttpChildHandle,\r
+ &gEfiHttpProtocolGuid,\r
+ gRedfishRestExDriverBinding.DriverBindingHandle,\r
+ ChildHandle\r
+ );\r
+\r
+ gBS->UninstallMultipleProtocolInterfaces (\r
+ Instance->ChildHandle,\r
+ &gEfiRestExProtocolGuid,\r
+ &Instance->RestEx,\r
+ NULL\r
+ );\r
+\r
+ goto ON_ERROR;\r
+ }\r
+\r
+ //\r
+ // Add it to the parent's child list.\r
+ //\r
+ OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
+\r
+ InsertTailList (&RestExSb->RestExChildrenList, &Instance->Link);\r
+ RestExSb->RestExChildrenNum++;\r
+\r
+ gBS->RestoreTPL (OldTpl);\r
+\r
+ return EFI_SUCCESS;\r
+\r
+ON_ERROR:\r
+\r
+ RestExDestroyInstance (Instance);\r
+ return Status;\r
+}\r
+\r
+/**\r
+ Destroys a child handle with a protocol installed on it.\r
+\r
+ The DestroyChild() function does the opposite of CreateChild(). It removes a protocol\r
+ that was installed by CreateChild() from ChildHandle. If the removed protocol is the\r
+ last protocol on ChildHandle, then ChildHandle is destroyed.\r
+\r
+ @param[in] This Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance.\r
+ @param[in] ChildHandle Handle of the child to destroy\r
+\r
+ @retval EFI_SUCCES The protocol was removed from ChildHandle.\r
+ @retval EFI_UNSUPPORTED ChildHandle does not support the protocol that is being removed.\r
+ @retval EFI_INVALID_PARAMETER Child handle is NULL.\r
+ @retval EFI_ACCESS_DENIED The protocol could not be removed from the ChildHandle\r
+ because its services are being used.\r
+ @retval other The child handle was not destroyed\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+RedfishRestExServiceBindingDestroyChild (\r
+ IN EFI_SERVICE_BINDING_PROTOCOL *This,\r
+ IN EFI_HANDLE ChildHandle\r
+ )\r
+{\r
+ RESTEX_SERVICE *RestExSb;\r
+ RESTEX_INSTANCE *Instance;\r
+\r
+ EFI_REST_EX_PROTOCOL *RestEx;\r
+ EFI_STATUS Status;\r
+ EFI_TPL OldTpl;\r
+\r
+ if ((This == NULL) || (ChildHandle == NULL)) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ //\r
+ // Retrieve the private context data structures\r
+ //\r
+ Status = gBS->OpenProtocol (\r
+ ChildHandle,\r
+ &gEfiRestExProtocolGuid,\r
+ (VOID **) &RestEx,\r
+ NULL,\r
+ NULL,\r
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+ );\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+\r
+ Instance = RESTEX_INSTANCE_FROM_THIS (RestEx);\r
+ RestExSb = RESTEX_SERVICE_FROM_THIS (This);\r
+\r
+ if (Instance->Service != RestExSb) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ if (Instance->InDestroy) {\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
+\r
+ Instance->InDestroy = TRUE;\r
+\r
+ //\r
+ // Close the Http protocol.\r
+ //\r
+ gBS->CloseProtocol (\r
+ RestExSb->HttpChildHandle,\r
+ &gEfiHttpProtocolGuid,\r
+ gRedfishRestExDriverBinding.DriverBindingHandle,\r
+ ChildHandle\r
+ );\r
+\r
+ gBS->CloseProtocol (\r
+ Instance->HttpIo.Handle,\r
+ &gEfiHttpProtocolGuid,\r
+ gRedfishRestExDriverBinding.DriverBindingHandle,\r
+ ChildHandle\r
+ );\r
+\r
+\r
+ gBS->RestoreTPL (OldTpl);\r
+\r
+ //\r
+ // Uninstall the RestEx protocol first to enable a top down destruction.\r
+ //\r
+ Status = gBS->UninstallProtocolInterface (\r
+ ChildHandle,\r
+ &gEfiRestExProtocolGuid,\r
+ RestEx\r
+ );\r
+\r
+ OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ Instance->InDestroy = FALSE;\r
+ gBS->RestoreTPL (OldTpl);\r
+ return Status;\r
+ }\r
+\r
+ RemoveEntryList (&Instance->Link);\r
+ RestExSb->RestExChildrenNum--;\r
+\r
+ gBS->RestoreTPL (OldTpl);\r
+\r
+ RestExDestroyInstance (Instance);\r
+ return EFI_SUCCESS;\r
+}\r
+\r
--- /dev/null
+/** @file\r
+ RedfishRestExDxe support functions definitions.\r
+\r
+ Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>\r
+ (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>\r
+\r
+ SPDX-License-Identifier: BSD-2-Clause-Patent\r
+\r
+**/\r
+\r
+#ifndef EFI_REDFISH_RESTEX_DRIVER_H_\r
+#define EFI_REDFISH_RESTEX_DRIVER_H_\r
+\r
+///\r
+/// Libraries classes\r
+///\r
+#include <Library/BaseLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/DevicePathLib.h>\r
+#include <Library/HttpIoLib.h>\r
+#include <Library/MemoryAllocationLib.h>\r
+#include <Library/NetLib.h>\r
+#include <Library/UefiLib.h>\r
+#include <Library/UefiBootServicesTableLib.h>\r
+#include <Library/UefiDriverEntryPoint.h>\r
+\r
+///\r
+/// UEFI Driver Model Protocols\r
+///\r
+#include <Protocol/DriverBinding.h>\r
+#include <Protocol/RestEx.h>\r
+#include <Protocol/ServiceBinding.h>\r
+\r
+///\r
+/// Protocol instances\r
+///\r
+extern EFI_COMPONENT_NAME_PROTOCOL gRedfishRestExComponentName;\r
+extern EFI_COMPONENT_NAME2_PROTOCOL gRedfishRestExComponentName2;\r
+extern EFI_UNICODE_STRING_TABLE *gRedfishRestExControllerNameTable;\r
+\r
+extern EFI_DRIVER_BINDING_PROTOCOL gRedfishRestExDriverBinding;\r
+extern EFI_SERVICE_BINDING_PROTOCOL mRedfishRestExServiceBinding;\r
+extern EFI_REST_EX_PROTOCOL mRedfishRestExProtocol;\r
+///\r
+/// RestEx service block\r
+///\r
+typedef struct _RESTEX_SERVICE RESTEX_SERVICE;\r
+\r
+///\r
+/// RestEx instance block\r
+///\r
+typedef struct _RESTEX_INSTANCE RESTEX_INSTANCE;\r
+\r
+///\r
+/// Driver Version\r
+///\r
+#define REDFISH_RESTEX_DRIVER_VERSION 0x0100\r
+\r
+#define RESTEX_SERVICE_SIGNATURE SIGNATURE_32 ('R', 'E', 'S', 'S')\r
+#define RESTEX_INSTANCE_SIGNATURE SIGNATURE_32 ('R', 'E', 'I', 'S')\r
+\r
+#define RESTEX_SERVICE_FROM_THIS(a) \\r
+ CR (a, RESTEX_SERVICE, ServiceBinding, RESTEX_SERVICE_SIGNATURE)\r
+\r
+#define RESTEX_INSTANCE_FROM_THIS(a) \\r
+ CR (a, RESTEX_INSTANCE, RestEx, RESTEX_INSTANCE_SIGNATURE)\r
+\r
+\r
+#define RESTEX_STATE_UNCONFIGED 0\r
+#define RESTEX_STATE_CONFIGED 1\r
+\r
+struct _RESTEX_SERVICE {\r
+ UINT32 Signature;\r
+ EFI_SERVICE_BINDING_PROTOCOL ServiceBinding;\r
+\r
+ UINT16 RestExChildrenNum;\r
+ LIST_ENTRY RestExChildrenList;\r
+\r
+ EFI_HANDLE ControllerHandle;\r
+ EFI_HANDLE ImageHandle;\r
+\r
+ //\r
+ // Use to establish the parent-child relationship.\r
+ //\r
+ EFI_HANDLE HttpChildHandle;\r
+\r
+ UINT32 Id;\r
+\r
+ EFI_REST_EX_SERVICE_INFO RestExServiceInfo;\r
+};\r
+\r
+#define RESTEX_INSTANCE_FLAGS_TLS_RETRY 0x00000001\r
+#define RESTEX_INSTANCE_FLAGS_TCP_ERROR_RETRY 0x00000002\r
+\r
+struct _RESTEX_INSTANCE {\r
+ UINT32 Signature;\r
+ LIST_ENTRY Link;\r
+\r
+ EFI_REST_EX_PROTOCOL RestEx;\r
+\r
+ INTN State;\r
+ BOOLEAN InDestroy;\r
+\r
+ RESTEX_SERVICE *Service;\r
+ EFI_HANDLE ChildHandle;\r
+\r
+ EFI_REST_EX_CONFIG_DATA ConfigData;\r
+\r
+ //\r
+ // HTTP_IO to access the HTTP service\r
+ //\r
+ HTTP_IO HttpIo;\r
+\r
+ UINT32 Flags;\r
+};\r
+\r
+typedef struct {\r
+ EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;\r
+ UINTN NumberOfChildren;\r
+ EFI_HANDLE *ChildHandleBuffer;\r
+} RESTEX_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT;\r
+\r
+/**\r
+ Provides a simple HTTP-like interface to send and receive resources from a REST service.\r
+\r
+ The SendReceive() function sends an HTTP request to this REST service, and returns a\r
+ response when the data is retrieved from the service. RequestMessage contains the HTTP\r
+ request to the REST resource identified by RequestMessage.Request.Url. The\r
+ ResponseMessage is the returned HTTP response for that request, including any HTTP\r
+ status.\r
+\r
+ @param[in] This Pointer to EFI_REST_EX_PROTOCOL instance for a particular\r
+ REST service.\r
+ @param[in] RequestMessage Pointer to the HTTP request data for this resource\r
+ @param[out] ResponseMessage Pointer to the HTTP response data obtained for this requested.\r
+\r
+ @retval EFI_SUCCESS operation succeeded.\r
+ @retval EFI_INVALID_PARAMETER This, RequestMessage, or ResponseMessage are NULL.\r
+ @retval EFI_DEVICE_ERROR An unexpected system or network error occurred.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+RedfishRestExSendReceive (\r
+ IN EFI_REST_EX_PROTOCOL *This,\r
+ IN EFI_HTTP_MESSAGE *RequestMessage,\r
+ OUT EFI_HTTP_MESSAGE *ResponseMessage\r
+ );\r
+\r
+/**\r
+ Obtain the current time from this REST service instance.\r
+\r
+ The GetServiceTime() function is an optional interface to obtain the current time from\r
+ this REST service instance. If this REST service does not support to retrieve the time,\r
+ this function returns EFI_UNSUPPORTED. This function must returns EFI_UNSUPPORTED if\r
+ EFI_REST_EX_SERVICE_TYPE returned in EFI_REST_EX_SERVICE_INFO from GetService() is\r
+ EFI_REST_EX_SERVICE_UNSPECIFIC.\r
+\r
+ @param[in] This Pointer to EFI_REST_EX_PROTOCOL instance for a particular\r
+ REST service.\r
+ @param[out] Time A pointer to storage to receive a snapshot of the current time of\r
+ the REST service.\r
+\r
+ @retval EFI_SUCCESS operation succeeded.\r
+ @retval EFI_INVALID_PARAMETER This or Time are NULL.\r
+ @retval EFI_UNSUPPORTED The RESTful service does not support returning the time.\r
+ @retval EFI_DEVICE_ERROR An unexpected system or network error occurred.\r
+ @retval EFI_NOT_READY The configuration of this instance is not set yet. Configure() must\r
+ be executed and returns successfully prior to invoke this function.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+RedfishRestExGetServiceTime (\r
+ IN EFI_REST_EX_PROTOCOL *This,\r
+ OUT EFI_TIME *Time\r
+ );\r
+\r
+/**\r
+ This function returns the information of REST service provided by this EFI REST EX driver instance.\r
+\r
+ The information such as the type of REST service and the access mode of REST EX driver instance\r
+ (In-band or Out-of-band) are described in EFI_REST_EX_SERVICE_INFO structure. For the vendor-specific\r
+ REST service, vendor-specific REST service information is returned in VendorSpecifcData.\r
+ REST EX driver designer is well know what REST service this REST EX driver instance intends to\r
+ communicate with. The designer also well know this driver instance is used to talk to BMC through\r
+ specific platform mechanism or talk to REST server through UEFI HTTP protocol. REST EX driver is\r
+ responsible to fill up the correct information in EFI_REST_EX_SERVICE_INFO. EFI_REST_EX_SERVICE_INFO\r
+ is referred by EFI REST clients to pickup the proper EFI REST EX driver instance to get and set resource.\r
+ GetService() is a basic and mandatory function which must be able to use even Configure() is not invoked\r
+ in previously.\r
+\r
+ @param[in] This Pointer to EFI_REST_EX_PROTOCOL instance for a particular\r
+ REST service.\r
+ @param[out] RestExServiceInfo Pointer to receive a pointer to EFI_REST_EX_SERVICE_INFO structure. The\r
+ format of EFI_REST_EX_SERVICE_INFO is version controlled for the future\r
+ extension. The version of EFI_REST_EX_SERVICE_INFO structure is returned\r
+ in the header within this structure. EFI REST client refers to the correct\r
+ format of structure according to the version number. The pointer to\r
+ EFI_REST_EX_SERVICE_INFO is a memory block allocated by EFI REST EX driver\r
+ instance. That is caller's responsibility to free this memory when this\r
+ structure is no longer needed. Refer to Related Definitions below for the\r
+ definitions of EFI_REST_EX_SERVICE_INFO structure.\r
+\r
+ @retval EFI_SUCCESS EFI_REST_EX_SERVICE_INFO is returned in RestExServiceInfo. This function\r
+ is not supported in this REST EX Protocol driver instance.\r
+ @retval EFI_UNSUPPORTED This function is not supported in this REST EX Protocol driver instance.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+RedfishRestExGetService (\r
+ IN EFI_REST_EX_PROTOCOL *This,\r
+ OUT EFI_REST_EX_SERVICE_INFO **RestExServiceInfo\r
+ );\r
+\r
+/**\r
+ This function returns operational configuration of current EFI REST EX child instance.\r
+\r
+ This function returns the current configuration of EFI REST EX child instance. The format of\r
+ operational configuration depends on the implementation of EFI REST EX driver instance. For\r
+ example, HTTP-aware EFI REST EX driver instance uses EFI HTTP protocol as the undying protocol\r
+ to communicate with REST service. In this case, the type of configuration is\r
+ EFI_REST_EX_CONFIG_TYPE_HTTP returned from GetService(). EFI_HTTP_CONFIG_DATA is used as EFI REST\r
+ EX configuration format and returned to EFI REST client. User has to type cast RestExConfigData\r
+ to EFI_HTTP_CONFIG_DATA. For those non HTTP-aware REST EX driver instances, the type of configuration\r
+ is EFI_REST_EX_CONFIG_TYPE_UNSPECIFIC returned from GetService(). In this case, the format of\r
+ returning data could be non industrial. Instead, the format of configuration data is system/platform\r
+ specific definition such as BMC mechanism used in EFI REST EX driver instance. EFI REST client and\r
+ EFI REST EX driver instance have to refer to the specific system /platform spec which is out of UEFI scope.\r
+\r
+ @param[in] This This is the EFI_REST_EX_PROTOCOL instance.\r
+ @param[out] RestExConfigData Pointer to receive a pointer to EFI_REST_EX_CONFIG_DATA.\r
+ The memory allocated for configuration data should be freed\r
+ by caller. See Related Definitions for the details.\r
+\r
+ @retval EFI_SUCCESS EFI_REST_EX_CONFIG_DATA is returned in successfully.\r
+ @retval EFI_UNSUPPORTED This function is not supported in this REST EX Protocol driver instance.\r
+ @retval EFI_NOT_READY The configuration of this instance is not set yet. Configure() must be\r
+ executed and returns successfully prior to invoke this function.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+RedfishRestExGetModeData (\r
+ IN EFI_REST_EX_PROTOCOL *This,\r
+ OUT EFI_REST_EX_CONFIG_DATA *RestExConfigData\r
+ );\r
+\r
+/**\r
+ This function is used to configure EFI REST EX child instance.\r
+\r
+ This function is used to configure the setting of underlying protocol of REST EX child\r
+ instance. The type of configuration is according to the implementation of EFI REST EX\r
+ driver instance. For example, HTTP-aware EFI REST EX driver instance uses EFI HTTP protocol\r
+ as the undying protocol to communicate with REST service. The type of configuration is\r
+ EFI_REST_EX_CONFIG_TYPE_HTTP and RestExConfigData is the same format with EFI_HTTP_CONFIG_DATA.\r
+ Akin to HTTP configuration, REST EX child instance can be configure to use different HTTP\r
+ local access point for the data transmission. Multiple REST clients may use different\r
+ configuration of HTTP to distinguish themselves, such as to use the different TCP port.\r
+ For those non HTTP-aware REST EX driver instance, the type of configuration is\r
+ EFI_REST_EX_CONFIG_TYPE_UNSPECIFIC. RestExConfigData refers to the non industrial standard.\r
+ Instead, the format of configuration data is system/platform specific definition such as BMC.\r
+ In this case, EFI REST client and EFI REST EX driver instance have to refer to the specific\r
+ system/platform spec which is out of the UEFI scope. Besides GetService()function, no other\r
+ EFI REST EX functions can be executed by this instance until Configure()is executed and returns\r
+ successfully. All other functions must returns EFI_NOT_READY if this instance is not configured\r
+ yet. Set RestExConfigData to NULL means to put EFI REST EX child instance into the unconfigured\r
+ state.\r
+\r
+ @param[in] This This is the EFI_REST_EX_PROTOCOL instance.\r
+ @param[in] RestExConfigData Pointer to EFI_REST_EX_CONFIG_DATA. See Related Definitions in\r
+ GetModeData() protocol interface.\r
+\r
+ @retval EFI_SUCCESS EFI_REST_EX_CONFIG_DATA is set in successfully.\r
+ @retval EFI_DEVICE_ERROR Configuration for this REST EX child instance is failed with the given\r
+ EFI_REST_EX_CONFIG_DATA.\r
+ @retval EFI_UNSUPPORTED This function is not supported in this REST EX Protocol driver instance.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+RedfishRestExConfigure (\r
+ IN EFI_REST_EX_PROTOCOL *This,\r
+ IN EFI_REST_EX_CONFIG_DATA RestExConfigData\r
+ );\r
+\r
+/**\r
+ This function sends REST request to REST service and signal caller's event asynchronously when\r
+ the final response is received by REST EX Protocol driver instance.\r
+\r
+ The essential design of this function is to handle asynchronous send/receive implicitly according\r
+ to REST service asynchronous request mechanism. Caller will get the notification once the response\r
+ is returned from REST service.\r
+\r
+ @param[in] This This is the EFI_REST_EX_PROTOCOL instance.\r
+ @param[in] RequestMessage This is the HTTP request message sent to REST service. Set RequestMessage\r
+ to NULL to cancel the previous asynchronous request associated with the\r
+ corresponding RestExToken. See descriptions for the details.\r
+ @param[in] RestExToken REST EX token which REST EX Protocol instance uses to notify REST client\r
+ the status of response of asynchronous REST request. See related definition\r
+ of EFI_REST_EX_TOKEN.\r
+ @param[in] TimeOutInMilliSeconds The pointer to the timeout in milliseconds which REST EX Protocol driver\r
+ instance refers as the duration to drop asynchronous REST request. NULL\r
+ pointer means no timeout for this REST request. REST EX Protocol driver\r
+ signals caller's event with EFI_STATUS set to EFI_TIMEOUT in RestExToken\r
+ if REST EX Protocol can't get the response from REST service within\r
+ TimeOutInMilliSeconds.\r
+\r
+ @retval EFI_SUCCESS Asynchronous REST request is established.\r
+ @retval EFI_UNSUPPORTED This REST EX Protocol driver instance doesn't support asynchronous request.\r
+ @retval EFI_TIMEOUT Asynchronous REST request is not established and timeout is expired.\r
+ @retval EFI_ABORT Previous asynchronous REST request has been canceled.\r
+ @retval EFI_DEVICE_ERROR Otherwise, returns EFI_DEVICE_ERROR for other errors according to HTTP Status Code.\r
+ @retval EFI_NOT_READY The configuration of this instance is not set yet. Configure() must be executed\r
+ and returns successfully prior to invoke this function.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+RedfishRestExAyncSendReceive (\r
+ IN EFI_REST_EX_PROTOCOL *This,\r
+ IN EFI_HTTP_MESSAGE *RequestMessage OPTIONAL,\r
+ IN EFI_REST_EX_TOKEN *RestExToken,\r
+ IN UINTN *TimeOutInMilliSeconds OPTIONAL\r
+ );\r
+\r
+/**\r
+ This function sends REST request to a REST Event service and signals caller's event\r
+ token asynchronously when the URI resource change event is received by REST EX\r
+ Protocol driver instance.\r
+\r
+ The essential design of this function is to monitor event implicitly according to\r
+ REST service event service mechanism. Caller will get the notification if certain\r
+ resource is changed.\r
+\r
+ @param[in] This This is the EFI_REST_EX_PROTOCOL instance.\r
+ @param[in] RequestMessage This is the HTTP request message sent to REST service. Set RequestMessage\r
+ to NULL to cancel the previous event service associated with the corresponding\r
+ RestExToken. See descriptions for the details.\r
+ @param[in] RestExToken REST EX token which REST EX Protocol driver instance uses to notify REST client\r
+ the URI resource which monitored by REST client has been changed. See the related\r
+ definition of EFI_REST_EX_TOKEN in EFI_REST_EX_PROTOCOL.AsyncSendReceive().\r
+\r
+ @retval EFI_SUCCESS Asynchronous REST request is established.\r
+ @retval EFI_UNSUPPORTED This REST EX Protocol driver instance doesn't support asynchronous request.\r
+ @retval EFI_ABORT Previous asynchronous REST request has been canceled or event subscription has been\r
+ delete from service.\r
+ @retval EFI_DEVICE_ERROR Otherwise, returns EFI_DEVICE_ERROR for other errors according to HTTP Status Code.\r
+ @retval EFI_NOT_READY The configuration of this instance is not set yet. Configure() must be executed\r
+ and returns successfully prior to invoke this function.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+RedfishRestExEventService (\r
+ IN EFI_REST_EX_PROTOCOL *This,\r
+ IN EFI_HTTP_MESSAGE *RequestMessage OPTIONAL,\r
+ IN EFI_REST_EX_TOKEN *RestExToken\r
+ );\r
+/**\r
+ Create a new TLS session becuase the previous on is closed.\r
+ status.\r
+\r
+ @param[in] Instance Pointer to EFI_REST_EX_PROTOCOL instance for a particular\r
+ REST service.\r
+ @retval EFI_SUCCESS operation succeeded.\r
+ @retval EFI Errors Other errors.\r
+\r
+**/\r
+EFI_STATUS\r
+ResetHttpTslSession (\r
+ IN RESTEX_INSTANCE *Instance\r
+);\r
+\r
+\r
+/**\r
+ Callback function which provided by user to remove one node in NetDestroyLinkList process.\r
+\r
+ @param[in] Entry The entry to be removed.\r
+ @param[in] Context Pointer to the callback context corresponds to the Context in NetDestroyLinkList.\r
+\r
+ @retval EFI_SUCCESS The entry has been removed successfully.\r
+ @retval Others Fail to remove the entry.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+RestExDestroyChildEntryInHandleBuffer (\r
+ IN LIST_ENTRY *Entry,\r
+ IN VOID *Context\r
+ );\r
+\r
+/**\r
+ Destroy the RestEx instance and recycle the resources.\r
+\r
+ @param[in] Instance The pointer to the RestEx instance.\r
+\r
+**/\r
+VOID\r
+RestExDestroyInstance (\r
+ IN RESTEX_INSTANCE *Instance\r
+ );\r
+\r
+/**\r
+ Create the RestEx instance and initialize it.\r
+\r
+ @param[in] Service The pointer to the RestEx service.\r
+ @param[out] Instance The pointer to the RestEx instance.\r
+\r
+ @retval EFI_OUT_OF_RESOURCES Failed to allocate resources.\r
+ @retval EFI_SUCCESS The RestEx instance is created.\r
+\r
+**/\r
+EFI_STATUS\r
+RestExCreateInstance (\r
+ IN RESTEX_SERVICE *Service,\r
+ OUT RESTEX_INSTANCE **Instance\r
+ );\r
+\r
+\r
+/**\r
+ Release all the resource used the RestEx service binding instance.\r
+\r
+ @param RestExSb The RestEx service binding instance.\r
+\r
+**/\r
+VOID\r
+RestExDestroyService (\r
+ IN RESTEX_SERVICE *RestExSb\r
+ );\r
+\r
+/**\r
+ Create then initialize a RestEx service binding instance.\r
+\r
+ @param[in] Controller The controller to install the RestEx service\r
+ binding on.\r
+ @param[in] Image The driver binding image of the RestEx driver.\r
+ @param[out] Service The variable to receive the created service\r
+ binding instance.\r
+\r
+ @retval EFI_OUT_OF_RESOURCES Failed to allocate resource to create the instance.\r
+ @retval EFI_SUCCESS The service instance is created for the controller.\r
+\r
+**/\r
+EFI_STATUS\r
+RestExCreateService (\r
+ IN EFI_HANDLE Controller,\r
+ IN EFI_HANDLE Image,\r
+ OUT RESTEX_SERVICE **Service\r
+ );\r
+\r
+/**\r
+ This is the declaration of an EFI image entry point. This entry point is\r
+ the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers including\r
+ both device drivers and bus drivers.\r
+\r
+ @param[in] ImageHandle The firmware allocated handle for the UEFI image.\r
+ @param[in] SystemTable A pointer to the EFI System Table.\r
+\r
+ @retval EFI_SUCCESS The operation completed successfully.\r
+ @retval Others An unexpected error occurred.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+RedfishRestExDriverEntryPoint (\r
+ IN EFI_HANDLE ImageHandle,\r
+ IN EFI_SYSTEM_TABLE *SystemTable\r
+ );\r
+\r
+/**\r
+ Tests to see if this driver supports a given controller. If a child device is provided,\r
+ it further tests to see if this driver supports creating a handle for the specified child device.\r
+\r
+ This function checks to see if the driver specified by This supports the device specified by\r
+ ControllerHandle. Drivers will typically use the device path attached to\r
+ ControllerHandle and/or the services from the bus I/O abstraction attached to\r
+ ControllerHandle to determine if the driver supports ControllerHandle. This function\r
+ may be called many times during platform initialization. In order to reduce boot times, the tests\r
+ performed by this function must be very small, and take as little time as possible to execute. This\r
+ function must not change the state of any hardware devices, and this function must be aware that the\r
+ device specified by ControllerHandle may already be managed by the same driver or a\r
+ different driver. This function must match its calls to AllocatePages() with FreePages(),\r
+ AllocatePool() with FreePool(), and OpenProtocol() with CloseProtocol().\r
+ Because ControllerHandle may have been previously started by the same driver, if a protocol is\r
+ already in the opened state, then it must not be closed with CloseProtocol(). This is required\r
+ to guarantee the state of ControllerHandle is not modified by this function.\r
+\r
+ @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.\r
+ @param[in] ControllerHandle The handle of the controller to test. This handle\r
+ must support a protocol interface that supplies\r
+ an I/O abstraction to the driver.\r
+ @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This\r
+ parameter is ignored by device drivers, and is optional for bus\r
+ drivers. For bus drivers, if this parameter is not NULL, then\r
+ the bus driver must determine if the bus controller specified\r
+ by ControllerHandle and the child controller specified\r
+ by RemainingDevicePath are both supported by this\r
+ bus driver.\r
+\r
+ @retval EFI_SUCCESS The device specified by ControllerHandle and\r
+ RemainingDevicePath is supported by the driver specified by This.\r
+ @retval EFI_ALREADY_STARTED The device specified by ControllerHandle and\r
+ RemainingDevicePath is already being managed by the driver\r
+ specified by This.\r
+ @retval EFI_ACCESS_DENIED The device specified by ControllerHandle and\r
+ RemainingDevicePath is already being managed by a different\r
+ driver or an application that requires exclusive access.\r
+ Currently not implemented.\r
+ @retval EFI_UNSUPPORTED The device specified by ControllerHandle and\r
+ RemainingDevicePath is not supported by the driver specified by This.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+RedfishRestExDriverBindingSupported (\r
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
+ IN EFI_HANDLE ControllerHandle,\r
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL\r
+ );\r
+\r
+/**\r
+ Starts a device controller or a bus controller.\r
+\r
+ The Start() function is designed to be invoked from the EFI boot service ConnectController().\r
+ As a result, much of the error checking on the parameters to Start() has been moved into this\r
+ common boot service. It is legal to call Start() from other locations,\r
+ but the following calling restrictions must be followed, or the system behavior will not be deterministic.\r
+ 1. ControllerHandle must be a valid EFI_HANDLE.\r
+ 2. If RemainingDevicePath is not NULL, then it must be a pointer to a naturally aligned\r
+ EFI_DEVICE_PATH_PROTOCOL.\r
+ 3. Prior to calling Start(), the Supported() function for the driver specified by This must\r
+ have been called with the same calling parameters, and Supported() must have returned EFI_SUCCESS.\r
+\r
+ @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.\r
+ @param[in] ControllerHandle The handle of the controller to start. This handle\r
+ must support a protocol interface that supplies\r
+ an I/O abstraction to the driver.\r
+ @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This\r
+ parameter is ignored by device drivers, and is optional for bus\r
+ drivers. For a bus driver, if this parameter is NULL, then handles\r
+ for all the children of Controller are created by this driver.\r
+ If this parameter is not NULL and the first Device Path Node is\r
+ not the End of Device Path Node, then only the handle for the\r
+ child device specified by the first Device Path Node of\r
+ RemainingDevicePath is created by this driver.\r
+ If the first Device Path Node of RemainingDevicePath is\r
+ the End of Device Path Node, no child handle is created by this\r
+ driver.\r
+\r
+ @retval EFI_SUCCESS The device was started.\r
+ @retval EFI_DEVICE_ERROR The device could not be started due to a device error.Currently not implemented.\r
+ @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.\r
+ @retval Others The driver failded to start the device.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+RedfishRestExDriverBindingStart (\r
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
+ IN EFI_HANDLE ControllerHandle,\r
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL\r
+ );\r
+\r
+/**\r
+ Stops a device controller or a bus controller.\r
+\r
+ The Stop() function is designed to be invoked from the EFI boot service DisconnectController().\r
+ As a result, much of the error checking on the parameters to Stop() has been moved\r
+ into this common boot service. It is legal to call Stop() from other locations,\r
+ but the following calling restrictions must be followed, or the system behavior will not be deterministic.\r
+ 1. ControllerHandle must be a valid EFI_HANDLE that was used on a previous call to this\r
+ same driver's Start() function.\r
+ 2. The first NumberOfChildren handles of ChildHandleBuffer must all be a valid\r
+ EFI_HANDLE. In addition, all of these handles must have been created in this driver's\r
+ Start() function, and the Start() function must have called OpenProtocol() on\r
+ ControllerHandle with an Attribute of EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER.\r
+\r
+ @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.\r
+ @param[in] ControllerHandle A handle to the device being stopped. The handle must\r
+ support a bus specific I/O protocol for the driver\r
+ to use to stop the device.\r
+ @param[in] NumberOfChildren The number of child device handles in ChildHandleBuffer.\r
+ @param[in] ChildHandleBuffer An array of child handles to be freed. May be NULL\r
+ if NumberOfChildren is 0.\r
+\r
+ @retval EFI_SUCCESS The device was stopped.\r
+ @retval EFI_DEVICE_ERROR The device could not be stopped due to a device error.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+RedfishRestExDriverBindingStop (\r
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
+ IN EFI_HANDLE ControllerHandle,\r
+ IN UINTN NumberOfChildren,\r
+ IN EFI_HANDLE *ChildHandleBuffer OPTIONAL\r
+ );\r
+\r
+/**\r
+ Creates a child handle and installs a protocol.\r
+\r
+ The CreateChild() function installs a protocol on ChildHandle.\r
+ If ChildHandle is a pointer to NULL, then a new handle is created and returned in ChildHandle.\r
+ If ChildHandle is not a pointer to NULL, then the protocol installs on the existing ChildHandle.\r
+\r
+ @param[in] This Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance.\r
+ @param[in] ChildHandle Pointer to the handle of the child to create. If it is NULL,\r
+ then a new handle is created. If it is a pointer to an existing UEFI handle,\r
+ then the protocol is added to the existing UEFI handle.\r
+\r
+ @retval EFI_SUCCES The protocol was added to ChildHandle.\r
+ @retval EFI_INVALID_PARAMETER ChildHandle is NULL.\r
+ @retval EFI_OUT_OF_RESOURCES There are not enough resources available to create\r
+ the child\r
+ @retval other The child handle was not created\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+RedfishRestExServiceBindingCreateChild (\r
+ IN EFI_SERVICE_BINDING_PROTOCOL *This,\r
+ IN EFI_HANDLE *ChildHandle\r
+ );\r
+\r
+/**\r
+ Destroys a child handle with a protocol installed on it.\r
+\r
+ The DestroyChild() function does the opposite of CreateChild(). It removes a protocol\r
+ that was installed by CreateChild() from ChildHandle. If the removed protocol is the\r
+ last protocol on ChildHandle, then ChildHandle is destroyed.\r
+\r
+ @param[in] This Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance.\r
+ @param[in] ChildHandle Handle of the child to destroy\r
+\r
+ @retval EFI_SUCCES The protocol was removed from ChildHandle.\r
+ @retval EFI_UNSUPPORTED ChildHandle does not support the protocol that is being removed.\r
+ @retval EFI_INVALID_PARAMETER Child handle is NULL.\r
+ @retval EFI_ACCESS_DENIED The protocol could not be removed from the ChildHandle\r
+ because its services are being used.\r
+ @retval other The child handle was not destroyed\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+RedfishRestExServiceBindingDestroyChild (\r
+ IN EFI_SERVICE_BINDING_PROTOCOL *This,\r
+ IN EFI_HANDLE ChildHandle\r
+ );\r
+#endif\r
--- /dev/null
+## @file\r
+# Implementation of Redfish EFI_REST_EX_PROTOCOL interfaces.\r
+#\r
+# Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>\r
+# (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>\r
+#\r
+# SPDX-License-Identifier: BSD-2-Clause-Patent\r
+#\r
+##\r
+\r
+[Defines]\r
+ INF_VERSION = 0x0001001b\r
+ BASE_NAME = RedfishRestExDxe\r
+ FILE_GUID = B64702DA-E6B5-43c8-8CE8-D253071E9D6C\r
+ MODULE_TYPE = UEFI_DRIVER\r
+ VERSION_STRING = 1.0\r
+ ENTRY_POINT = RedfishRestExDriverEntryPoint\r
+ UNLOAD_IMAGE = NetLibDefaultUnload\r
+ MODULE_UNI_FILE = RedfishRestExDxe.uni\r
+\r
+[Packages]\r
+ MdePkg/MdePkg.dec\r
+ MdeModulePkg/MdeModulePkg.dec\r
+ NetworkPkg/NetworkPkg.dec\r
+ RedfishPkg/RedfishPkg.dec\r
+\r
+[Sources]\r
+ ComponentName.c\r
+ RedfishRestExDriver.c\r
+ RedfishRestExDriver.h\r
+ RedfishRestExImpl.c\r
+ RedfishRestExProtocol.c\r
+ RedfishRestExInternal.h\r
+\r
+[LibraryClasses]\r
+ BaseLib\r
+ BaseMemoryLib\r
+ DebugLib\r
+ DevicePathLib\r
+ DpcLib\r
+ HttpLib\r
+ HttpIoLib\r
+ PrintLib\r
+ MemoryAllocationLib\r
+ NetLib\r
+ UefiLib\r
+ UefiBootServicesTableLib\r
+ UefiDriverEntryPoint\r
+ UefiRuntimeServicesTableLib\r
+\r
+[Protocols]\r
+ gEfiRestExServiceBindingProtocolGuid ## BY_START\r
+ gEfiRestExProtocolGuid ## BY_START\r
+ gEfiHttpServiceBindingProtocolGuid ## TO_START\r
+ gEfiHttpProtocolGuid ## TO_START\r
+ gEfiDevicePathProtocolGuid ## TO_START\r
+\r
+[Pcd]\r
+ gEfiRedfishPkgTokenSpaceGuid.PcdRedfishRestExServiceAccessModeInBand ## CONSUMES\r
+\r
+[UserExtensions.TianoCore."ExtraFiles"]\r
+ RedfishRestExDxeExtra.uni\r
+\r
--- /dev/null
+// /** @file\r
+// Redfish UEFI RESTEX DXE Driver.\r
+//\r
+// This driver provides Redfish UEFI RESTEX protocols.\r
+//\r
+// Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>\r
+// (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>\r
+//\r
+// SPDX-License-Identifier: BSD-2-Clause-Patent\r
+//\r
+// **/\r
+\r
+#string STR_MODULE_ABSTRACT #language en-US "UEFI Redfish RESTEX service"\r
+\r
+#string STR_MODULE_DESCRIPTION #language en-US "This driver provides Redfish EFI RESTEX Protocol and Redfish EFI RESREX Service Binding Protocol."\r
+\r
--- /dev/null
+// /** @file\r
+// RestExDxe Localized Strings and Content\r
+//\r
+// Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>\r
+// (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>\r
+//\r
+// SPDX-License-Identifier: BSD-2-Clause-Patent\r
+//\r
+// **/\r
+\r
+#string STR_PROPERTIES_MODULE_NAME\r
+#language en-US\r
+"Redfish UEFI RESTEX DXE"\r
+\r
+\r
--- /dev/null
+/** @file\r
+ RestExDxe support functions implementation.\r
+\r
+ Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>\r
+ (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>\r
+\r
+ SPDX-License-Identifier: BSD-2-Clause-Patent\r
+\r
+**/\r
+#include <Uefi.h>\r
+#include "RedfishRestExInternal.h"\r
+\r
+/**\r
+ Create a new TLS session becuase the previous on is closed.\r
+ status.\r
+\r
+ @param[in] Instance Pointer to EFI_REST_EX_PROTOCOL instance for a particular\r
+ REST service.\r
+ @retval EFI_SUCCESS operation succeeded.\r
+ @retval EFI_ERROR Other errors.\r
+\r
+**/\r
+EFI_STATUS\r
+ResetHttpTslSession (\r
+ IN RESTEX_INSTANCE *Instance\r
+)\r
+{\r
+ EFI_STATUS Status;\r
+\r
+ DEBUG ((DEBUG_INFO, "%a: TCP connection is finished. Could be TSL session closure, reset HTTP instance for the new TLS session.\n", __FUNCTION__));\r
+\r
+ Status = Instance->HttpIo.Http->Configure (Instance->HttpIo.Http, NULL);\r
+ if (EFI_ERROR (Status)) {\r
+ DEBUG ((DEBUG_ERROR, "%a: Error to reset HTTP instance.\n", __FUNCTION__));\r
+ return Status;\r
+ }\r
+ Status = Instance->HttpIo.Http->Configure(Instance->HttpIo.Http, &((EFI_REST_EX_HTTP_CONFIG_DATA *)Instance->ConfigData)->HttpConfigData);\r
+ if (EFI_ERROR (Status)) {\r
+ DEBUG ((DEBUG_ERROR, "%a: Error to re-initiate HTTP instance.\n", __FUNCTION__));\r
+ }\r
+ return Status;\r
+}\r
+/**\r
+ This function check\r
+\r
+ @param[in] Instance Pointer to EFI_REST_EX_PROTOCOL instance for a particular\r
+ REST service.\r
+ @param[in] HttpIoReceiveStatus This is the status return from HttpIoRecvResponse\r
+\r
+ @retval EFI_SUCCESS The payload receive from Redfish service in sucessfully.\r
+ @retval EFI_NOT_READY May need to resend the HTTP request.\r
+ @retval EFI_DEVICE_ERROR Something wrong and can't be resolved.\r
+ @retval Others Other errors as indicated.\r
+\r
+**/\r
+EFI_STATUS\r
+RedfishCheckHttpReceiveStatus (\r
+ IN RESTEX_INSTANCE *Instance,\r
+ IN EFI_STATUS HttpIoReceiveStatus\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_STATUS ReturnStatus;\r
+\r
+ if (!EFI_ERROR (HttpIoReceiveStatus)){\r
+ ReturnStatus = EFI_SUCCESS;\r
+ } else if (EFI_ERROR (HttpIoReceiveStatus) && HttpIoReceiveStatus != EFI_CONNECTION_FIN) {\r
+ if ((Instance->Flags & RESTEX_INSTANCE_FLAGS_TCP_ERROR_RETRY) == 0) {\r
+ DEBUG ((DEBUG_ERROR, "%a: TCP error, reset HTTP session.\n", __FUNCTION__));\r
+ Instance->Flags |= RESTEX_INSTANCE_FLAGS_TCP_ERROR_RETRY;\r
+ gBS->Stall (500);\r
+ Status = ResetHttpTslSession (Instance);\r
+ if (EFI_ERROR (Status)) {\r
+ DEBUG ((DEBUG_ERROR, "%a: Reset HTTP instance fail.\n", __FUNCTION__));\r
+ ReturnStatus = EFI_DEVICE_ERROR;\r
+ } else {\r
+ return EFI_NOT_READY;\r
+ }\r
+ } else {\r
+ ReturnStatus = EFI_DEVICE_ERROR;\r
+ }\r
+ } else {\r
+ if (HttpIoReceiveStatus == EFI_CONNECTION_FIN) {\r
+ if ((Instance->Flags & RESTEX_INSTANCE_FLAGS_TLS_RETRY) != 0) {\r
+ DEBUG ((DEBUG_ERROR, "%a: REST_EX Send and receive fail even with a new TLS session.\n", __FUNCTION__));\r
+ ReturnStatus = EFI_DEVICE_ERROR;\r
+ }\r
+ Instance->Flags |= RESTEX_INSTANCE_FLAGS_TLS_RETRY;\r
+ Status = ResetHttpTslSession (Instance);\r
+ if (EFI_ERROR (Status)) {\r
+ DEBUG ((DEBUG_ERROR, "%a: Reset HTTP instance fail.\n", __FUNCTION__));\r
+ ReturnStatus = EFI_DEVICE_ERROR;\r
+ }\r
+ return EFI_NOT_READY;\r
+ }\r
+ }\r
+ //\r
+ // Clean TLS new session retry and error try flags.\r
+ //\r
+ Instance->Flags &= ~ (RESTEX_INSTANCE_FLAGS_TLS_RETRY | RESTEX_INSTANCE_FLAGS_TCP_ERROR_RETRY);\r
+ return ReturnStatus;\r
+}\r
+\r
+/**\r
+ This function send the HTTP request without body to see\r
+ if the write to URL is permitted by Redfish service. This function\r
+ checks if the HTTP request has Content-length in HTTP header. If yes,\r
+ set HTTP body to NULL and then send to service. Check the HTTP status\r
+ for the firther actions.\r
+\r
+ @param[in] This Pointer to EFI_REST_EX_PROTOCOL instance for a particular\r
+ REST service.\r
+ @param[in] RequestMessage Pointer to the HTTP request data for this resource\r
+ @param[in] PreservedRequestHeaders The pointer to save the request headers\r
+ @param[in] ItsWrite This is write method to URL.\r
+\r
+ @retval EFI_INVALID_PARAMETER Improper given parameters.\r
+ @retval EFI_SUCCESS This HTTP request is free to send to Redfish service.\r
+ @retval EFI_OUT_OF_RESOURCES NOt enough memory to process.\r
+ @retval EFI_ACCESS_DENIED Not allowed to write to this URL.\r
+\r
+ @retval Others Other errors as indicated.\r
+\r
+**/\r
+EFI_STATUS\r
+RedfishHttpAddExpectation (\r
+ IN EFI_REST_EX_PROTOCOL *This,\r
+ IN EFI_HTTP_MESSAGE *RequestMessage,\r
+ IN EFI_HTTP_HEADER **PreservedRequestHeaders,\r
+ IN BOOLEAN *ItsWrite\r
+ )\r
+{\r
+ EFI_HTTP_HEADER *NewHeaders;\r
+\r
+ if (This == NULL || RequestMessage == NULL) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ *ItsWrite = FALSE;\r
+ if (PreservedRequestHeaders != NULL) {\r
+ *PreservedRequestHeaders = RequestMessage->Headers;\r
+ }\r
+\r
+ if ((RequestMessage->Data.Request->Method != HttpMethodPut) && (RequestMessage->Data.Request->Method != HttpMethodPost) &&\r
+ (RequestMessage->Data.Request->Method != HttpMethodPatch)) {\r
+ return EFI_SUCCESS;\r
+ }\r
+ *ItsWrite = TRUE;\r
+\r
+ NewHeaders = AllocateZeroPool((RequestMessage->HeaderCount + 1) * sizeof(EFI_HTTP_HEADER));\r
+ CopyMem ((VOID*)NewHeaders, (VOID *)RequestMessage->Headers, RequestMessage->HeaderCount * sizeof (EFI_HTTP_HEADER));\r
+ HttpSetFieldNameAndValue (NewHeaders + RequestMessage->HeaderCount, HTTP_HEADER_EXPECT, HTTP_EXPECT_100_CONTINUE);\r
+ RequestMessage->HeaderCount ++;\r
+ RequestMessage->Headers = NewHeaders;\r
+ return EFI_SUCCESS;\r
+}\r
+\r
--- /dev/null
+/** @file\r
+ RedfishRestExDxe support functions definitions.\r
+\r
+ Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>\r
+ (C) Copyright 2019-2020 Hewlett Packard Enterprise Development LP<BR>\r
+\r
+ SPDX-License-Identifier: BSD-2-Clause-Patent\r
+\r
+**/\r
+\r
+#ifndef EFI_REDFISH_RESTEX_INTERNAL_H_\r
+#define EFI_REDFISH_RESTEX_INTERNAL_H_\r
+\r
+///\r
+/// Libraries classes\r
+///\r
+#include <Library/BaseLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/DevicePathLib.h>\r
+#include <Library/HttpIoLib.h>\r
+#include <Library/MemoryAllocationLib.h>\r
+#include <Library/NetLib.h>\r
+#include <Library/UefiLib.h>\r
+#include <Library/UefiBootServicesTableLib.h>\r
+#include <Library/UefiDriverEntryPoint.h>\r
+\r
+///\r
+/// UEFI Driver Model Protocols\r
+///\r
+#include <Protocol/DriverBinding.h>\r
+#include <Protocol/RestEx.h>\r
+#include <Protocol/ServiceBinding.h>\r
+\r
+#include "RedfishRestExDriver.h"\r
+\r
+/**\r
+ This function check\r
+\r
+ @param[in] Instance Pointer to EFI_REST_EX_PROTOCOL instance for a particular\r
+ REST service.\r
+ @param[in] HttpReceiveEfiStatus This is the status return from HttpIoRecvResponse\r
+\r
+ @retval EFI_SUCCESS The payload receive from Redfish service in sucessfully.\r
+ @retval EFI_NOT_READY May need to resend the HTTP request.\r
+ @retval EFI_DEVICE_ERROR Something wrong and can't be resolved.\r
+ @retval Others Other errors as indicated.\r
+\r
+**/\r
+EFI_STATUS\r
+RedfishCheckHttpReceiveStatus (\r
+ IN RESTEX_INSTANCE *Instance,\r
+ IN EFI_STATUS HttpIoReceiveStatus\r
+ );\r
+\r
+/**\r
+ This function send the HTTP request without body to see\r
+ if the write to URL is permitted by Redfish service. This function\r
+ checks if the HTTP request has Content-length in HTTP header. If yes,\r
+ set HTTP body to NULL and then send to service. Check the HTTP status\r
+ for the firther actions.\r
+\r
+ @param[in] This Pointer to EFI_REST_EX_PROTOCOL instance for a particular\r
+ REST service.\r
+ @param[in] RequestMessage Pointer to the HTTP request data for this resource\r
+ @param[in] PreservedRequestHeaders The pointer to save the request headers\r
+ @param[in] ItsWrite This is write method to URL.\r
+\r
+ @retval EFI_INVALID_PARAMETER Improper given parameters.\r
+ @retval EFI_SUCCESS This HTTP request is free to send to Redfish service.\r
+ @retval EFI_OUT_OF_RESOURCES NOt enough memory to process.\r
+ @retval EFI_ACCESS_DENIED Not allowed to write to this URL.\r
+\r
+ @retval Others Other errors as indicated.\r
+\r
+**/\r
+EFI_STATUS\r
+RedfishHttpAddExpectation (\r
+ IN EFI_REST_EX_PROTOCOL *This,\r
+ IN EFI_HTTP_MESSAGE *RequestMessage,\r
+ IN EFI_HTTP_HEADER **PreservedRequestHeaders,\r
+ IN BOOLEAN *ItsWrite\r
+ );\r
+\r
+/**\r
+ Provides a simple HTTP-like interface to send and receive resources from a REST service.\r
+\r
+ The SendReceive() function sends an HTTP request to this REST service, and returns a\r
+ response when the data is retrieved from the service. RequestMessage contains the HTTP\r
+ request to the REST resource identified by RequestMessage.Request.Url. The\r
+ ResponseMessage is the returned HTTP response for that request, including any HTTP\r
+ status.\r
+\r
+ @param[in] This Pointer to EFI_REST_EX_PROTOCOL instance for a particular\r
+ REST service.\r
+ @param[in] RequestMessage Pointer to the HTTP request data for this resource\r
+ @param[out] ResponseMessage Pointer to the HTTP response data obtained for this requested.\r
+\r
+ @retval EFI_SUCCESS operation succeeded.\r
+ @retval EFI_INVALID_PARAMETER This, RequestMessage, or ResponseMessage are NULL.\r
+ @retval EFI_DEVICE_ERROR An unexpected system or network error occurred.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+RedfishRestExSendReceive (\r
+ IN EFI_REST_EX_PROTOCOL *This,\r
+ IN EFI_HTTP_MESSAGE *RequestMessage,\r
+ OUT EFI_HTTP_MESSAGE *ResponseMessage\r
+ );\r
+\r
+/**\r
+ Obtain the current time from this REST service instance.\r
+\r
+ The GetServiceTime() function is an optional interface to obtain the current time from\r
+ this REST service instance. If this REST service does not support to retrieve the time,\r
+ this function returns EFI_UNSUPPORTED. This function must returns EFI_UNSUPPORTED if\r
+ EFI_REST_EX_SERVICE_TYPE returned in EFI_REST_EX_SERVICE_INFO from GetService() is\r
+ EFI_REST_EX_SERVICE_UNSPECIFIC.\r
+\r
+ @param[in] This Pointer to EFI_REST_EX_PROTOCOL instance for a particular\r
+ REST service.\r
+ @param[out] Time A pointer to storage to receive a snapshot of the current time of\r
+ the REST service.\r
+\r
+ @retval EFI_SUCCESS operation succeeded.\r
+ @retval EFI_INVALID_PARAMETER This or Time are NULL.\r
+ @retval EFI_UNSUPPORTED The RESTful service does not support returning the time.\r
+ @retval EFI_DEVICE_ERROR An unexpected system or network error occurred.\r
+ @retval EFI_NOT_READY The configuration of this instance is not set yet. Configure() must\r
+ be executed and returns successfully prior to invoke this function.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+RedfishRestExGetServiceTime (\r
+ IN EFI_REST_EX_PROTOCOL *This,\r
+ OUT EFI_TIME *Time\r
+ );\r
+\r
+/**\r
+ This function returns the information of REST service provided by this EFI REST EX driver instance.\r
+\r
+ The information such as the type of REST service and the access mode of REST EX driver instance\r
+ (In-band or Out-of-band) are described in EFI_REST_EX_SERVICE_INFO structure. For the vendor-specific\r
+ REST service, vendor-specific REST service information is returned in VendorSpecifcData.\r
+ REST EX driver designer is well know what REST service this REST EX driver instance intends to\r
+ communicate with. The designer also well know this driver instance is used to talk to BMC through\r
+ specific platform mechanism or talk to REST server through UEFI HTTP protocol. REST EX driver is\r
+ responsible to fill up the correct information in EFI_REST_EX_SERVICE_INFO. EFI_REST_EX_SERVICE_INFO\r
+ is referred by EFI REST clients to pickup the proper EFI REST EX driver instance to get and set resource.\r
+ GetService() is a basic and mandatory function which must be able to use even Configure() is not invoked\r
+ in previously.\r
+\r
+ @param[in] This Pointer to EFI_REST_EX_PROTOCOL instance for a particular\r
+ REST service.\r
+ @param[out] RestExServiceInfo Pointer to receive a pointer to EFI_REST_EX_SERVICE_INFO structure. The\r
+ format of EFI_REST_EX_SERVICE_INFO is version controlled for the future\r
+ extension. The version of EFI_REST_EX_SERVICE_INFO structure is returned\r
+ in the header within this structure. EFI REST client refers to the correct\r
+ format of structure according to the version number. The pointer to\r
+ EFI_REST_EX_SERVICE_INFO is a memory block allocated by EFI REST EX driver\r
+ instance. That is caller's responsibility to free this memory when this\r
+ structure is no longer needed. Refer to Related Definitions below for the\r
+ definitions of EFI_REST_EX_SERVICE_INFO structure.\r
+\r
+ @retval EFI_SUCCESS EFI_REST_EX_SERVICE_INFO is returned in RestExServiceInfo. This function\r
+ is not supported in this REST EX Protocol driver instance.\r
+ @retval EFI_UNSUPPORTED This function is not supported in this REST EX Protocol driver instance.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+RedfishRestExGetService (\r
+ IN EFI_REST_EX_PROTOCOL *This,\r
+ OUT EFI_REST_EX_SERVICE_INFO **RestExServiceInfo\r
+ );\r
+\r
+/**\r
+ This function returns operational configuration of current EFI REST EX child instance.\r
+\r
+ This function returns the current configuration of EFI REST EX child instance. The format of\r
+ operational configuration depends on the implementation of EFI REST EX driver instance. For\r
+ example, HTTP-aware EFI REST EX driver instance uses EFI HTTP protocol as the undying protocol\r
+ to communicate with REST service. In this case, the type of configuration is\r
+ EFI_REST_EX_CONFIG_TYPE_HTTP returned from GetService(). EFI_HTTP_CONFIG_DATA is used as EFI REST\r
+ EX configuration format and returned to EFI REST client. User has to type cast RestExConfigData\r
+ to EFI_HTTP_CONFIG_DATA. For those non HTTP-aware REST EX driver instances, the type of configuration\r
+ is EFI_REST_EX_CONFIG_TYPE_UNSPECIFIC returned from GetService(). In this case, the format of\r
+ returning data could be non industrial. Instead, the format of configuration data is system/platform\r
+ specific definition such as BMC mechanism used in EFI REST EX driver instance. EFI REST client and\r
+ EFI REST EX driver instance have to refer to the specific system /platform spec which is out of UEFI scope.\r
+\r
+ @param[in] This This is the EFI_REST_EX_PROTOCOL instance.\r
+ @param[out] RestExConfigData Pointer to receive a pointer to EFI_REST_EX_CONFIG_DATA.\r
+ The memory allocated for configuration data should be freed\r
+ by caller. See Related Definitions for the details.\r
+\r
+ @retval EFI_SUCCESS EFI_REST_EX_CONFIG_DATA is returned in successfully.\r
+ @retval EFI_UNSUPPORTED This function is not supported in this REST EX Protocol driver instance.\r
+ @retval EFI_NOT_READY The configuration of this instance is not set yet. Configure() must be\r
+ executed and returns successfully prior to invoke this function.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+RedfishRestExGetModeData (\r
+ IN EFI_REST_EX_PROTOCOL *This,\r
+ OUT EFI_REST_EX_CONFIG_DATA *RestExConfigData\r
+ );\r
+\r
+/**\r
+ This function is used to configure EFI REST EX child instance.\r
+\r
+ This function is used to configure the setting of underlying protocol of REST EX child\r
+ instance. The type of configuration is according to the implementation of EFI REST EX\r
+ driver instance. For example, HTTP-aware EFI REST EX driver instance uses EFI HTTP protocol\r
+ as the undying protocol to communicate with REST service. The type of configuration is\r
+ EFI_REST_EX_CONFIG_TYPE_HTTP and RestExConfigData is the same format with EFI_HTTP_CONFIG_DATA.\r
+ Akin to HTTP configuration, REST EX child instance can be configure to use different HTTP\r
+ local access point for the data transmission. Multiple REST clients may use different\r
+ configuration of HTTP to distinguish themselves, such as to use the different TCP port.\r
+ For those non HTTP-aware REST EX driver instance, the type of configuration is\r
+ EFI_REST_EX_CONFIG_TYPE_UNSPECIFIC. RestExConfigData refers to the non industrial standard.\r
+ Instead, the format of configuration data is system/platform specific definition such as BMC.\r
+ In this case, EFI REST client and EFI REST EX driver instance have to refer to the specific\r
+ system/platform spec which is out of the UEFI scope. Besides GetService()function, no other\r
+ EFI REST EX functions can be executed by this instance until Configure()is executed and returns\r
+ successfully. All other functions must returns EFI_NOT_READY if this instance is not configured\r
+ yet. Set RestExConfigData to NULL means to put EFI REST EX child instance into the unconfigured\r
+ state.\r
+\r
+ @param[in] This This is the EFI_REST_EX_PROTOCOL instance.\r
+ @param[in] RestExConfigData Pointer to EFI_REST_EX_CONFIG_DATA. See Related Definitions in\r
+ GetModeData() protocol interface.\r
+\r
+ @retval EFI_SUCCESS EFI_REST_EX_CONFIG_DATA is set in successfully.\r
+ @retval EFI_DEVICE_ERROR Configuration for this REST EX child instance is failed with the given\r
+ EFI_REST_EX_CONFIG_DATA.\r
+ @retval EFI_UNSUPPORTED This function is not supported in this REST EX Protocol driver instance.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+RedfishRestExConfigure (\r
+ IN EFI_REST_EX_PROTOCOL *This,\r
+ IN EFI_REST_EX_CONFIG_DATA RestExConfigData\r
+ );\r
+\r
+/**\r
+ This function sends REST request to REST service and signal caller's event asynchronously when\r
+ the final response is received by REST EX Protocol driver instance.\r
+\r
+ The essential design of this function is to handle asynchronous send/receive implicitly according\r
+ to REST service asynchronous request mechanism. Caller will get the notification once the response\r
+ is returned from REST service.\r
+\r
+ @param[in] This This is the EFI_REST_EX_PROTOCOL instance.\r
+ @param[in] RequestMessage This is the HTTP request message sent to REST service. Set RequestMessage\r
+ to NULL to cancel the previous asynchronous request associated with the\r
+ corresponding RestExToken. See descriptions for the details.\r
+ @param[in] RestExToken REST EX token which REST EX Protocol instance uses to notify REST client\r
+ the status of response of asynchronous REST request. See related definition\r
+ of EFI_REST_EX_TOKEN.\r
+ @param[in] TimeOutInMilliSeconds The pointer to the timeout in milliseconds which REST EX Protocol driver\r
+ instance refers as the duration to drop asynchronous REST request. NULL\r
+ pointer means no timeout for this REST request. REST EX Protocol driver\r
+ signals caller's event with EFI_STATUS set to EFI_TIMEOUT in RestExToken\r
+ if REST EX Protocol can't get the response from REST service within\r
+ TimeOutInMilliSeconds.\r
+\r
+ @retval EFI_SUCCESS Asynchronous REST request is established.\r
+ @retval EFI_UNSUPPORTED This REST EX Protocol driver instance doesn't support asynchronous request.\r
+ @retval EFI_TIMEOUT Asynchronous REST request is not established and timeout is expired.\r
+ @retval EFI_ABORT Previous asynchronous REST request has been canceled.\r
+ @retval EFI_DEVICE_ERROR Otherwise, returns EFI_DEVICE_ERROR for other errors according to HTTP Status Code.\r
+ @retval EFI_NOT_READY The configuration of this instance is not set yet. Configure() must be executed\r
+ and returns successfully prior to invoke this function.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+RedfishRestExAyncSendReceive (\r
+ IN EFI_REST_EX_PROTOCOL *This,\r
+ IN EFI_HTTP_MESSAGE *RequestMessage OPTIONAL,\r
+ IN EFI_REST_EX_TOKEN *RestExToken,\r
+ IN UINTN *TimeOutInMilliSeconds OPTIONAL\r
+ );\r
+\r
+/**\r
+ This function sends REST request to a REST Event service and signals caller's event\r
+ token asynchronously when the URI resource change event is received by REST EX\r
+ Protocol driver instance.\r
+\r
+ The essential design of this function is to monitor event implicitly according to\r
+ REST service event service mechanism. Caller will get the notification if certain\r
+ resource is changed.\r
+\r
+ @param[in] This This is the EFI_REST_EX_PROTOCOL instance.\r
+ @param[in] RequestMessage This is the HTTP request message sent to REST service. Set RequestMessage\r
+ to NULL to cancel the previous event service associated with the corresponding\r
+ RestExToken. See descriptions for the details.\r
+ @param[in] RestExToken REST EX token which REST EX Protocol driver instance uses to notify REST client\r
+ the URI resource which monitored by REST client has been changed. See the related\r
+ definition of EFI_REST_EX_TOKEN in EFI_REST_EX_PROTOCOL.AsyncSendReceive().\r
+\r
+ @retval EFI_SUCCESS Asynchronous REST request is established.\r
+ @retval EFI_UNSUPPORTED This REST EX Protocol driver instance doesn't support asynchronous request.\r
+ @retval EFI_ABORT Previous asynchronous REST request has been canceled or event subscription has been\r
+ delete from service.\r
+ @retval EFI_DEVICE_ERROR Otherwise, returns EFI_DEVICE_ERROR for other errors according to HTTP Status Code.\r
+ @retval EFI_NOT_READY The configuration of this instance is not set yet. Configure() must be executed\r
+ and returns successfully prior to invoke this function.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+RedfishRestExEventService (\r
+ IN EFI_REST_EX_PROTOCOL *This,\r
+ IN EFI_HTTP_MESSAGE *RequestMessage OPTIONAL,\r
+ IN EFI_REST_EX_TOKEN *RestExToken\r
+ );\r
+/**\r
+ Create a new TLS session becuase the previous on is closed.\r
+ status.\r
+\r
+ @param[in] Instance Pointer to EFI_REST_EX_PROTOCOL instance for a particular\r
+ REST service.\r
+ @retval EFI_SUCCESS operation succeeded.\r
+ @retval EFI Errors Other errors.\r
+\r
+**/\r
+EFI_STATUS\r
+ResetHttpTslSession (\r
+ IN RESTEX_INSTANCE *Instance\r
+);\r
+\r
+\r
+/**\r
+ Callback function which provided by user to remove one node in NetDestroyLinkList process.\r
+\r
+ @param[in] Entry The entry to be removed.\r
+ @param[in] Context Pointer to the callback context corresponds to the Context in NetDestroyLinkList.\r
+\r
+ @retval EFI_SUCCESS The entry has been removed successfully.\r
+ @retval Others Fail to remove the entry.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+RestExDestroyChildEntryInHandleBuffer (\r
+ IN LIST_ENTRY *Entry,\r
+ IN VOID *Context\r
+ );\r
+\r
+/**\r
+ Destroy the RestEx instance and recycle the resources.\r
+\r
+ @param[in] Instance The pointer to the RestEx instance.\r
+\r
+**/\r
+VOID\r
+RestExDestroyInstance (\r
+ IN RESTEX_INSTANCE *Instance\r
+ );\r
+\r
+/**\r
+ Create the RestEx instance and initialize it.\r
+\r
+ @param[in] Service The pointer to the RestEx service.\r
+ @param[out] Instance The pointer to the RestEx instance.\r
+\r
+ @retval EFI_OUT_OF_RESOURCES Failed to allocate resources.\r
+ @retval EFI_SUCCESS The RestEx instance is created.\r
+\r
+**/\r
+EFI_STATUS\r
+RestExCreateInstance (\r
+ IN RESTEX_SERVICE *Service,\r
+ OUT RESTEX_INSTANCE **Instance\r
+ );\r
+\r
+\r
+/**\r
+ Release all the resource used the RestEx service binding instance.\r
+\r
+ @param[in] RestExSb The RestEx service binding instance.\r
+\r
+**/\r
+VOID\r
+RestExDestroyService (\r
+ IN RESTEX_SERVICE *RestExSb\r
+ );\r
+\r
+/**\r
+ Create then initialize a RestEx service binding instance.\r
+\r
+ @param[in] Controller The controller to install the RestEx service\r
+ binding on.\r
+ @param[in] Image The driver binding image of the RestEx driver.\r
+ @param[out] Service The variable to receive the created service\r
+ binding instance.\r
+\r
+ @retval EFI_OUT_OF_RESOURCES Failed to allocate resource to create the instance.\r
+ @retval EFI_SUCCESS The service instance is created for the controller.\r
+\r
+**/\r
+EFI_STATUS\r
+RestExCreateService (\r
+ IN EFI_HANDLE Controller,\r
+ IN EFI_HANDLE Image,\r
+ OUT RESTEX_SERVICE **Service\r
+ );\r
+\r
+/**\r
+ This is the declaration of an EFI image entry point. This entry point is\r
+ the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers including\r
+ both device drivers and bus drivers.\r
+\r
+ @param[in] ImageHandle The firmware allocated handle for the UEFI image.\r
+ @param[in] SystemTable A pointer to the EFI System Table.\r
+\r
+ @retval EFI_SUCCESS The operation completed successfully.\r
+ @retval Others An unexpected error occurred.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+RedfishRestExDriverEntryPoint (\r
+ IN EFI_HANDLE ImageHandle,\r
+ IN EFI_SYSTEM_TABLE *SystemTable\r
+ );\r
+\r
+/**\r
+ Tests to see if this driver supports a given controller. If a child device is provided,\r
+ it further tests to see if this driver supports creating a handle for the specified child device.\r
+\r
+ This function checks to see if the driver specified by This supports the device specified by\r
+ ControllerHandle. Drivers will typically use the device path attached to\r
+ ControllerHandle and/or the services from the bus I/O abstraction attached to\r
+ ControllerHandle to determine if the driver supports ControllerHandle. This function\r
+ may be called many times during platform initialization. In order to reduce boot times, the tests\r
+ performed by this function must be very small, and take as little time as possible to execute. This\r
+ function must not change the state of any hardware devices, and this function must be aware that the\r
+ device specified by ControllerHandle may already be managed by the same driver or a\r
+ different driver. This function must match its calls to AllocatePages() with FreePages(),\r
+ AllocatePool() with FreePool(), and OpenProtocol() with CloseProtocol().\r
+ Because ControllerHandle may have been previously started by the same driver, if a protocol is\r
+ already in the opened state, then it must not be closed with CloseProtocol(). This is required\r
+ to guarantee the state of ControllerHandle is not modified by this function.\r
+\r
+ @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.\r
+ @param[in] ControllerHandle The handle of the controller to test. This handle\r
+ must support a protocol interface that supplies\r
+ an I/O abstraction to the driver.\r
+ @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This\r
+ parameter is ignored by device drivers, and is optional for bus\r
+ drivers. For bus drivers, if this parameter is not NULL, then\r
+ the bus driver must determine if the bus controller specified\r
+ by ControllerHandle and the child controller specified\r
+ by RemainingDevicePath are both supported by this\r
+ bus driver.\r
+\r
+ @retval EFI_SUCCESS The device specified by ControllerHandle and\r
+ RemainingDevicePath is supported by the driver specified by This.\r
+ @retval EFI_ALREADY_STARTED The device specified by ControllerHandle and\r
+ RemainingDevicePath is already being managed by the driver\r
+ specified by This.\r
+ @retval EFI_ACCESS_DENIED The device specified by ControllerHandle and\r
+ RemainingDevicePath is already being managed by a different\r
+ driver or an application that requires exclusive access.\r
+ Currently not implemented.\r
+ @retval EFI_UNSUPPORTED The device specified by ControllerHandle and\r
+ RemainingDevicePath is not supported by the driver specified by This.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+RedfishRestExDriverBindingSupported (\r
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
+ IN EFI_HANDLE ControllerHandle,\r
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL\r
+ );\r
+\r
+/**\r
+ Starts a device controller or a bus controller.\r
+\r
+ The Start() function is designed to be invoked from the EFI boot service ConnectController().\r
+ As a result, much of the error checking on the parameters to Start() has been moved into this\r
+ common boot service. It is legal to call Start() from other locations,\r
+ but the following calling restrictions must be followed, or the system behavior will not be deterministic.\r
+ 1. ControllerHandle must be a valid EFI_HANDLE.\r
+ 2. If RemainingDevicePath is not NULL, then it must be a pointer to a naturally aligned\r
+ EFI_DEVICE_PATH_PROTOCOL.\r
+ 3. Prior to calling Start(), the Supported() function for the driver specified by This must\r
+ have been called with the same calling parameters, and Supported() must have returned EFI_SUCCESS.\r
+\r
+ @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.\r
+ @param[in] ControllerHandle The handle of the controller to start. This handle\r
+ must support a protocol interface that supplies\r
+ an I/O abstraction to the driver.\r
+ @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This\r
+ parameter is ignored by device drivers, and is optional for bus\r
+ drivers. For a bus driver, if this parameter is NULL, then handles\r
+ for all the children of Controller are created by this driver.\r
+ If this parameter is not NULL and the first Device Path Node is\r
+ not the End of Device Path Node, then only the handle for the\r
+ child device specified by the first Device Path Node of\r
+ RemainingDevicePath is created by this driver.\r
+ If the first Device Path Node of RemainingDevicePath is\r
+ the End of Device Path Node, no child handle is created by this\r
+ driver.\r
+\r
+ @retval EFI_SUCCESS The device was started.\r
+ @retval EFI_DEVICE_ERROR The device could not be started due to a device error.Currently not implemented.\r
+ @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.\r
+ @retval Others The driver failded to start the device.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+RedfishRestExDriverBindingStart (\r
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
+ IN EFI_HANDLE ControllerHandle,\r
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL\r
+ );\r
+\r
+/**\r
+ Stops a device controller or a bus controller.\r
+\r
+ The Stop() function is designed to be invoked from the EFI boot service DisconnectController().\r
+ As a result, much of the error checking on the parameters to Stop() has been moved\r
+ into this common boot service. It is legal to call Stop() from other locations,\r
+ but the following calling restrictions must be followed, or the system behavior will not be deterministic.\r
+ 1. ControllerHandle must be a valid EFI_HANDLE that was used on a previous call to this\r
+ same driver's Start() function.\r
+ 2. The first NumberOfChildren handles of ChildHandleBuffer must all be a valid\r
+ EFI_HANDLE. In addition, all of these handles must have been created in this driver's\r
+ Start() function, and the Start() function must have called OpenProtocol() on\r
+ ControllerHandle with an Attribute of EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER.\r
+\r
+ @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.\r
+ @param[in] ControllerHandle A handle to the device being stopped. The handle must\r
+ support a bus specific I/O protocol for the driver\r
+ to use to stop the device.\r
+ @param[in] NumberOfChildren The number of child device handles in ChildHandleBuffer.\r
+ @param[in] ChildHandleBuffer An array of child handles to be freed. May be NULL\r
+ if NumberOfChildren is 0.\r
+\r
+ @retval EFI_SUCCESS The device was stopped.\r
+ @retval EFI_DEVICE_ERROR The device could not be stopped due to a device error.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+RedfishRestExDriverBindingStop (\r
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
+ IN EFI_HANDLE ControllerHandle,\r
+ IN UINTN NumberOfChildren,\r
+ IN EFI_HANDLE *ChildHandleBuffer OPTIONAL\r
+ );\r
+\r
+/**\r
+ Creates a child handle and installs a protocol.\r
+\r
+ The CreateChild() function installs a protocol on ChildHandle.\r
+ If ChildHandle is a pointer to NULL, then a new handle is created and returned in ChildHandle.\r
+ If ChildHandle is not a pointer to NULL, then the protocol installs on the existing ChildHandle.\r
+\r
+ @param[in] This Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance.\r
+ @param[in] ChildHandle Pointer to the handle of the child to create. If it is NULL,\r
+ then a new handle is created. If it is a pointer to an existing UEFI handle,\r
+ then the protocol is added to the existing UEFI handle.\r
+\r
+ @retval EFI_SUCCES The protocol was added to ChildHandle.\r
+ @retval EFI_INVALID_PARAMETER ChildHandle is NULL.\r
+ @retval EFI_OUT_OF_RESOURCES There are not enough resources available to create\r
+ the child\r
+ @retval other The child handle was not created\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+RedfishRestExServiceBindingCreateChild (\r
+ IN EFI_SERVICE_BINDING_PROTOCOL *This,\r
+ IN EFI_HANDLE *ChildHandle\r
+ );\r
+\r
+/**\r
+ Destroys a child handle with a protocol installed on it.\r
+\r
+ The DestroyChild() function does the opposite of CreateChild(). It removes a protocol\r
+ that was installed by CreateChild() from ChildHandle. If the removed protocol is the\r
+ last protocol on ChildHandle, then ChildHandle is destroyed.\r
+\r
+ @param[in] This Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance.\r
+ @param[in] ChildHandle Handle of the child to destroy\r
+\r
+ @retval EFI_SUCCES The protocol was removed from ChildHandle.\r
+ @retval EFI_UNSUPPORTED ChildHandle does not support the protocol that is being removed.\r
+ @retval EFI_INVALID_PARAMETER Child handle is NULL.\r
+ @retval EFI_ACCESS_DENIED The protocol could not be removed from the ChildHandle\r
+ because its services are being used.\r
+ @retval other The child handle was not destroyed\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+RedfishRestExServiceBindingDestroyChild (\r
+ IN EFI_SERVICE_BINDING_PROTOCOL *This,\r
+ IN EFI_HANDLE ChildHandle\r
+ );\r
+#endif\r
--- /dev/null
+/** @file\r
+ Implementation of Redfish EFI_REST_EX_PROTOCOL interfaces.\r
+\r
+ Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>\r
+ (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>\r
+\r
+ SPDX-License-Identifier: BSD-2-Clause-Patent\r
+\r
+**/\r
+#include <Uefi.h>\r
+#include "RedfishRestExInternal.h"\r
+\r
+EFI_REST_EX_PROTOCOL mRedfishRestExProtocol = {\r
+ RedfishRestExSendReceive,\r
+ RedfishRestExGetServiceTime,\r
+ RedfishRestExGetService,\r
+ RedfishRestExGetModeData,\r
+ RedfishRestExConfigure,\r
+ RedfishRestExAyncSendReceive,\r
+ RedfishRestExEventService\r
+};\r
+\r
+/**\r
+ Provides a simple HTTP-like interface to send and receive resources from a REST service.\r
+\r
+ The SendReceive() function sends an HTTP request to this REST service, and returns a\r
+ response when the data is retrieved from the service. RequestMessage contains the HTTP\r
+ request to the REST resource identified by RequestMessage.Request.Url. The\r
+ ResponseMessage is the returned HTTP response for that request, including any HTTP\r
+ status.\r
+\r
+ @param[in] This Pointer to EFI_REST_EX_PROTOCOL instance for a particular\r
+ REST service.\r
+ @param[in] RequestMessage Pointer to the HTTP request data for this resource\r
+ @param[out] ResponseMessage Pointer to the HTTP response data obtained for this requested.\r
+\r
+ @retval EFI_SUCCESS operation succeeded.\r
+ @retval EFI_INVALID_PARAMETER This, RequestMessage, or ResponseMessage are NULL.\r
+ @retval EFI_DEVICE_ERROR An unexpected system or network error occurred.\r
+ @retval EFI_ACCESS_DENIED HTTP method is not allowed on this URL.\r
+ @retval EFI_BAD_BUFFER_SIZE The payload is to large to be handled on server side.\r
+ @retval EFI_UNSUPPORTED Unsupported HTTP response.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+RedfishRestExSendReceive (\r
+ IN EFI_REST_EX_PROTOCOL *This,\r
+ IN EFI_HTTP_MESSAGE *RequestMessage,\r
+ OUT EFI_HTTP_MESSAGE *ResponseMessage\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ RESTEX_INSTANCE *Instance;\r
+ HTTP_IO_RESPONSE_DATA *ResponseData;\r
+ UINTN TotalReceivedSize;\r
+ UINTN Index;\r
+ LIST_ENTRY *ChunkListLink;\r
+ HTTP_IO_CHUNKS *ThisChunk;\r
+ BOOLEAN CopyChunkData;\r
+ BOOLEAN MediaPresent;\r
+ EFI_HTTP_HEADER *PreservedRequestHeaders;\r
+ BOOLEAN ItsWrite;\r
+ BOOLEAN IsGetChunkedTransfer;\r
+ HTTP_IO_SEND_CHUNK_PROCESS SendChunkProcess;\r
+ HTTP_IO_SEND_NON_CHUNK_PROCESS SendNonChunkProcess;\r
+ EFI_HTTP_MESSAGE ChunkTransferRequestMessage;\r
+\r
+ Status = EFI_SUCCESS;\r
+ ResponseData = NULL;\r
+ IsGetChunkedTransfer = FALSE;\r
+ SendChunkProcess = HttpIoSendChunkNone;\r
+ SendNonChunkProcess = HttpIoSendNonChunkNone;\r
+\r
+ //\r
+ // Validate the parameters\r
+ //\r
+ if ((This == NULL) || (RequestMessage == NULL) || ResponseMessage == NULL) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ Instance = RESTEX_INSTANCE_FROM_THIS (This);\r
+\r
+ //\r
+ // Check Media Status.\r
+ //\r
+ MediaPresent = TRUE;\r
+ NetLibDetectMedia (Instance->Service->ControllerHandle, &MediaPresent);\r
+ if (!MediaPresent) {\r
+ DEBUG ((DEBUG_INFO, "RedfishRestExSendReceive(): No MediaPresent.\n"));\r
+ return EFI_NO_MEDIA;\r
+ }\r
+\r
+ DEBUG ((DEBUG_INFO, "\nRedfishRestExSendReceive():\n"));\r
+ DEBUG ((DEBUG_INFO, "*** Perform HTTP Request Method - %d, URL: %s\n", RequestMessage->Data.Request->Method, RequestMessage->Data.Request->Url));\r
+\r
+ //\r
+ // Add header "Expect" to server, only for URL write.\r
+ //\r
+ Status = RedfishHttpAddExpectation (This, RequestMessage, &PreservedRequestHeaders, &ItsWrite);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+ if (ItsWrite == TRUE) {\r
+ if (RequestMessage->BodyLength > HTTP_IO_MAX_SEND_PAYLOAD) {\r
+ //\r
+ // Send chunked transfer.\r
+ //\r
+ SendChunkProcess ++;\r
+ CopyMem ((VOID *)&ChunkTransferRequestMessage, (VOID *)RequestMessage, sizeof (EFI_HTTP_MESSAGE));\r
+ } else {\r
+ SendNonChunkProcess ++;\r
+ }\r
+ }\r
+ReSendRequest:;\r
+ //\r
+ // Send out the request to REST service.\r
+ //\r
+ if (ItsWrite == TRUE) {\r
+ //\r
+ // This is write to URI\r
+ //\r
+ if (SendChunkProcess > HttpIoSendChunkNone) {\r
+ //\r
+ // This is chunk transfer for writing large payload.\r
+ // Send request header first and then handle the\r
+ // following request message body using chunk transfer.\r
+ //\r
+ do {\r
+ Status = HttpIoSendChunkedTransfer(\r
+ &(Instance->HttpIo),\r
+ &SendChunkProcess,\r
+ &ChunkTransferRequestMessage\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ goto ON_EXIT;\r
+ }\r
+ } while (SendChunkProcess == HttpIoSendChunkContent || SendChunkProcess == HttpIoSendChunkEndChunk);\r
+ } else {\r
+ //\r
+ // This is the non-chunk transfer, send request header first and then\r
+ // handle the following request message body using chunk transfer.\r
+ //\r
+ Status = HttpIoSendRequest(\r
+ &(Instance->HttpIo),\r
+ (SendNonChunkProcess == HttpIoSendNonChunkContent)? NULL: RequestMessage->Data.Request,\r
+ (SendNonChunkProcess == HttpIoSendNonChunkContent)? 0: RequestMessage->HeaderCount,\r
+ (SendNonChunkProcess == HttpIoSendNonChunkContent)? NULL: RequestMessage->Headers,\r
+ (SendNonChunkProcess == HttpIoSendNonChunkHeaderZeroContent)? 0: RequestMessage->BodyLength,\r
+ (SendNonChunkProcess == HttpIoSendNonChunkHeaderZeroContent)? NULL: RequestMessage->Body\r
+ );\r
+ }\r
+ } else {\r
+ //\r
+ // This is read from URI.\r
+ //\r
+ Status = HttpIoSendRequest(\r
+ &(Instance->HttpIo),\r
+ RequestMessage->Data.Request,\r
+ RequestMessage->HeaderCount,\r
+ RequestMessage->Headers,\r
+ RequestMessage->BodyLength,\r
+ RequestMessage->Body\r
+ );\r
+ }\r
+ if (EFI_ERROR (Status)) {\r
+ goto ON_EXIT;\r
+ }\r
+\r
+ //\r
+ // ResponseMessage->Data.Response is to indicate whether to receive the HTTP header or not.\r
+ // ResponseMessage->BodyLength/ResponseMessage->Body are to indicate whether to receive the response body or not.\r
+ // Clean the previous buffers and all of them will be allocated later according to the actual situation.\r
+ //\r
+ if (ResponseMessage->Data.Response != NULL) {\r
+ FreePool(ResponseMessage->Data.Response);\r
+ ResponseMessage->Data.Response = NULL;\r
+ }\r
+\r
+ ResponseMessage->BodyLength = 0;\r
+ if (ResponseMessage->Body != NULL) {\r
+ FreePool(ResponseMessage->Body);\r
+ ResponseMessage->Body = NULL;\r
+ }\r
+\r
+ //\r
+ // Use zero BodyLength to only receive the response headers.\r
+ //\r
+ ResponseData = AllocateZeroPool (sizeof(HTTP_IO_RESPONSE_DATA));\r
+ if (ResponseData == NULL) {\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ goto ON_EXIT;\r
+ }\r
+\r
+ DEBUG ((DEBUG_INFO, "Receiving HTTP response and headers...\n"));\r
+ Status = RedfishCheckHttpReceiveStatus (\r
+ Instance,\r
+ HttpIoRecvResponse (\r
+ &(Instance->HttpIo),\r
+ TRUE,\r
+ ResponseData\r
+ )\r
+ );\r
+ if (Status == EFI_NOT_READY) {\r
+ goto ReSendRequest;\r
+ } else if (Status == EFI_DEVICE_ERROR) {\r
+ goto ON_EXIT;\r
+ }\r
+ //\r
+ // Restore the headers if it ever changed in RedfishHttpAddExpectation().\r
+ //\r
+ if (RequestMessage->Headers != PreservedRequestHeaders) {\r
+ FreePool (RequestMessage->Headers);\r
+ RequestMessage->Headers = PreservedRequestHeaders; // Restore headers before we adding "Expect".\r
+ RequestMessage->HeaderCount --; // Minus one header count for "Expect".\r
+ }\r
+\r
+ DEBUG ((DEBUG_INFO, "HTTP Response StatusCode - %d:", ResponseData->Response.StatusCode));\r
+ if (ResponseData->Response.StatusCode == HTTP_STATUS_200_OK) {\r
+ DEBUG ((DEBUG_INFO, "HTTP_STATUS_200_OK\n"));\r
+\r
+ if (SendChunkProcess == HttpIoSendChunkHeaderZeroContent) {\r
+ DEBUG ((DEBUG_INFO, "This is chunk transfer, start to send all chunks.", ResponseData->Response.StatusCode));\r
+ SendChunkProcess ++;\r
+ goto ReSendRequest;\r
+ }\r
+ } else if (ResponseData->Response.StatusCode == HTTP_STATUS_413_REQUEST_ENTITY_TOO_LARGE) {\r
+ DEBUG ((DEBUG_INFO, "HTTP_STATUS_413_REQUEST_ENTITY_TOO_LARGE\n"));\r
+\r
+ Status = EFI_BAD_BUFFER_SIZE;\r
+ goto ON_EXIT;\r
+ } else if (ResponseData->Response.StatusCode == HTTP_STATUS_405_METHOD_NOT_ALLOWED){\r
+ DEBUG ((DEBUG_ERROR, "HTTP_STATUS_405_METHOD_NOT_ALLOWED\n"));\r
+\r
+ Status = EFI_ACCESS_DENIED;\r
+ goto ON_EXIT;\r
+ } else if (ResponseData->Response.StatusCode == HTTP_STATUS_400_BAD_REQUEST) {\r
+ DEBUG ((DEBUG_INFO, "HTTP_STATUS_400_BAD_REQUEST\n"));\r
+ if (SendChunkProcess == HttpIoSendChunkHeaderZeroContent) {\r
+ DEBUG ((DEBUG_INFO, "Bad request may caused by zero length chunk. Try to send all chunks...\n"));\r
+ SendChunkProcess ++;\r
+ goto ReSendRequest;\r
+ }\r
+ } else if (ResponseData->Response.StatusCode == HTTP_STATUS_100_CONTINUE) {\r
+ DEBUG ((DEBUG_INFO, "HTTP_STATUS_100_CONTINUE\n"));\r
+ if (SendChunkProcess == HttpIoSendChunkHeaderZeroContent) {\r
+ //\r
+ // We get HTTP_STATUS_100_CONTINUE to send the body using chunk transfer.\r
+ //\r
+ DEBUG ((DEBUG_INFO, "HTTP_STATUS_100_CONTINUE for chunk transfer...\n"));\r
+ SendChunkProcess ++;\r
+ goto ReSendRequest;\r
+ }\r
+ if (SendNonChunkProcess == HttpIoSendNonChunkHeaderZeroContent) {\r
+ DEBUG ((DEBUG_INFO, "HTTP_STATUS_100_CONTINUE for non chunk transfer...\n"));\r
+ SendNonChunkProcess ++;\r
+ goto ReSendRequest;\r
+ }\r
+ //\r
+ // It's the REST protocol's responsibility to handle the interim HTTP response (e.g. 100 Continue Informational),\r
+ // and return the final response content to the caller.\r
+ //\r
+ if (ResponseData->Headers != NULL && ResponseData->HeaderCount != 0) {\r
+ FreePool (ResponseData->Headers);\r
+ }\r
+ ZeroMem (ResponseData, sizeof(HTTP_IO_RESPONSE_DATA));\r
+ Status = HttpIoRecvResponse (\r
+ &(Instance->HttpIo),\r
+ TRUE,\r
+ ResponseData\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ goto ON_EXIT;\r
+ }\r
+ } else {\r
+ DEBUG ((DEBUG_ERROR, "This HTTP Status is not handled!\n"));\r
+ Status = EFI_UNSUPPORTED;\r
+ goto ON_EXIT;\r
+ }\r
+\r
+ //\r
+ // Ready to return the StatusCode, Header info and BodyLength.\r
+ //\r
+ ResponseMessage->Data.Response = AllocateZeroPool (sizeof (EFI_HTTP_RESPONSE_DATA));\r
+ if (ResponseMessage->Data.Response == NULL) {\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ goto ON_EXIT;\r
+ }\r
+\r
+ ResponseMessage->Data.Response->StatusCode = ResponseData->Response.StatusCode;\r
+ ResponseMessage->HeaderCount = ResponseData->HeaderCount;\r
+ ResponseMessage->Headers = ResponseData->Headers;\r
+\r
+ //\r
+ // Get response message body.\r
+ //\r
+ if (ResponseMessage->HeaderCount > 0) {\r
+ Status = HttpIoGetContentLength (ResponseMessage->HeaderCount, ResponseMessage->Headers, &ResponseMessage->BodyLength);\r
+ if (EFI_ERROR (Status) && Status != EFI_NOT_FOUND) {\r
+ goto ON_EXIT;\r
+ }\r
+\r
+ if (Status == EFI_NOT_FOUND) {\r
+ ASSERT (ResponseMessage->BodyLength == 0);\r
+ }\r
+\r
+ if (ResponseMessage->BodyLength == 0) {\r
+ //\r
+ // Check if Chunked Transfer Coding.\r
+ //\r
+ Status = HttpIoGetChunkedTransferContent (\r
+ &(Instance->HttpIo),\r
+ ResponseMessage->HeaderCount,\r
+ ResponseMessage->Headers,\r
+ &ChunkListLink,\r
+ &ResponseMessage->BodyLength\r
+ );\r
+ if (EFI_ERROR (Status) && Status != EFI_NOT_FOUND) {\r
+ goto ON_EXIT;\r
+ }\r
+ if (Status == EFI_SUCCESS &&\r
+ ChunkListLink != NULL &&\r
+ !IsListEmpty(ChunkListLink) &&\r
+ ResponseMessage->BodyLength != 0) {\r
+ IsGetChunkedTransfer = TRUE;\r
+ //\r
+ // Copy data to Message body.\r
+ //\r
+ CopyChunkData = TRUE;\r
+ ResponseMessage->Body = AllocateZeroPool (ResponseMessage->BodyLength);\r
+ if (ResponseMessage->Body == NULL) {\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ CopyChunkData = FALSE;\r
+ }\r
+ Index = 0;\r
+ while (!IsListEmpty(ChunkListLink)) {\r
+ ThisChunk = (HTTP_IO_CHUNKS *)GetFirstNode (ChunkListLink);\r
+ if (CopyChunkData) {\r
+ CopyMem(((UINT8 *)ResponseMessage->Body + Index), (UINT8 *)ThisChunk->Data, ThisChunk->Length);\r
+ Index += ThisChunk->Length;\r
+ }\r
+ RemoveEntryList (&ThisChunk->NextChunk);\r
+ FreePool ((VOID *)ThisChunk->Data);\r
+ FreePool ((VOID *)ThisChunk);\r
+ };\r
+ FreePool ((VOID *)ChunkListLink);\r
+ }\r
+ }\r
+ Status = EFI_SUCCESS;\r
+ }\r
+\r
+ //\r
+ // Ready to return the Body from REST service if have any.\r
+ //\r
+ if (ResponseMessage->BodyLength > 0 && !IsGetChunkedTransfer) {\r
+ ResponseData->HeaderCount = 0;\r
+ ResponseData->Headers = NULL;\r
+\r
+ ResponseMessage->Body = AllocateZeroPool (ResponseMessage->BodyLength);\r
+ if (ResponseMessage->Body == NULL) {\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ goto ON_EXIT;\r
+ }\r
+\r
+ //\r
+ // Only receive the Body.\r
+ //\r
+ TotalReceivedSize = 0;\r
+ while (TotalReceivedSize < ResponseMessage->BodyLength) {\r
+ ResponseData->BodyLength = ResponseMessage->BodyLength - TotalReceivedSize;\r
+ ResponseData->Body = (CHAR8 *) ResponseMessage->Body + TotalReceivedSize;\r
+ Status = HttpIoRecvResponse (\r
+ &(Instance->HttpIo),\r
+ FALSE,\r
+ ResponseData\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ goto ON_EXIT;\r
+ }\r
+\r
+ TotalReceivedSize += ResponseData->BodyLength;\r
+ }\r
+ DEBUG ((DEBUG_INFO, "Total of lengh of Response :%d\n", TotalReceivedSize));\r
+ }\r
+ DEBUG ((DEBUG_INFO, "RedfishRestExSendReceive()- EFI_STATUS: %r\n", Status));\r
+\r
+ON_EXIT:\r
+\r
+ if (ResponseData != NULL) {\r
+ FreePool (ResponseData);\r
+ }\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ if (ResponseMessage->Data.Response != NULL) {\r
+ FreePool (ResponseMessage->Data.Response);\r
+ ResponseMessage->Data.Response = NULL;\r
+ }\r
+\r
+ if (ResponseMessage->Body != NULL) {\r
+ FreePool (ResponseMessage->Body);\r
+ ResponseMessage->Body = NULL;\r
+ }\r
+ }\r
+ return Status;\r
+}\r
+\r
+/**\r
+ Obtain the current time from this REST service instance.\r
+\r
+ The GetServiceTime() function is an optional interface to obtain the current time from\r
+ this REST service instance. If this REST service does not support to retrieve the time,\r
+ this function returns EFI_UNSUPPORTED. This function must returns EFI_UNSUPPORTED if\r
+ EFI_REST_EX_SERVICE_TYPE returned in EFI_REST_EX_SERVICE_INFO from GetService() is\r
+ EFI_REST_EX_SERVICE_UNSPECIFIC.\r
+\r
+ @param[in] This Pointer to EFI_REST_EX_PROTOCOL instance for a particular\r
+ REST service.\r
+ @param[out] Time A pointer to storage to receive a snapshot of the current time of\r
+ the REST service.\r
+\r
+ @retval EFI_SUCCESS operation succeeded.\r
+ @retval EFI_INVALID_PARAMETER This or Time are NULL.\r
+ @retval EFI_UNSUPPORTED The RESTful service does not support returning the time.\r
+ @retval EFI_DEVICE_ERROR An unexpected system or network error occurred.\r
+ @retval EFI_NOT_READY The configuration of this instance is not set yet. Configure() must\r
+ be executed and returns successfully prior to invoke this function.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+RedfishRestExGetServiceTime (\r
+ IN EFI_REST_EX_PROTOCOL *This,\r
+ OUT EFI_TIME *Time\r
+ )\r
+{\r
+ return EFI_UNSUPPORTED;\r
+}\r
+\r
+/**\r
+ This function returns the information of REST service provided by this EFI REST EX driver instance.\r
+\r
+ The information such as the type of REST service and the access mode of REST EX driver instance\r
+ (In-band or Out-of-band) are described in EFI_REST_EX_SERVICE_INFO structure. For the vendor-specific\r
+ REST service, vendor-specific REST service information is returned in VendorSpecifcData.\r
+ REST EX driver designer is well know what REST service this REST EX driver instance intends to\r
+ communicate with. The designer also well know this driver instance is used to talk to BMC through\r
+ specific platform mechanism or talk to REST server through UEFI HTTP protocol. REST EX driver is\r
+ responsible to fill up the correct information in EFI_REST_EX_SERVICE_INFO. EFI_REST_EX_SERVICE_INFO\r
+ is referred by EFI REST clients to pickup the proper EFI REST EX driver instance to get and set resource.\r
+ GetService() is a basic and mandatory function which must be able to use even Configure() is not invoked\r
+ in previously.\r
+\r
+ @param[in] This Pointer to EFI_REST_EX_PROTOCOL instance for a particular\r
+ REST service.\r
+ @param[out] RestExServiceInfo Pointer to receive a pointer to EFI_REST_EX_SERVICE_INFO structure. The\r
+ format of EFI_REST_EX_SERVICE_INFO is version controlled for the future\r
+ extension. The version of EFI_REST_EX_SERVICE_INFO structure is returned\r
+ in the header within this structure. EFI REST client refers to the correct\r
+ format of structure according to the version number. The pointer to\r
+ EFI_REST_EX_SERVICE_INFO is a memory block allocated by EFI REST EX driver\r
+ instance. That is caller's responsibility to free this memory when this\r
+ structure is no longer needed. Refer to Related Definitions below for the\r
+ definitions of EFI_REST_EX_SERVICE_INFO structure.\r
+\r
+ @retval EFI_SUCCESS EFI_REST_EX_SERVICE_INFO is returned in RestExServiceInfo. This function\r
+ is not supported in this REST EX Protocol driver instance.\r
+ @retval EFI_UNSUPPORTED This function is not supported in this REST EX Protocol driver instance.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+RedfishRestExGetService (\r
+ IN EFI_REST_EX_PROTOCOL *This,\r
+ OUT EFI_REST_EX_SERVICE_INFO **RestExServiceInfo\r
+ )\r
+{\r
+ EFI_TPL OldTpl;\r
+ RESTEX_INSTANCE *Instance;\r
+ EFI_REST_EX_SERVICE_INFO *ServiceInfo;\r
+\r
+ ServiceInfo = NULL;\r
+\r
+ if (This == NULL || RestExServiceInfo == NULL) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
+\r
+ Instance = RESTEX_INSTANCE_FROM_THIS (This);\r
+\r
+ ServiceInfo = AllocateZeroPool (sizeof (EFI_REST_EX_SERVICE_INFO));\r
+ if (ServiceInfo == NULL) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+\r
+ CopyMem (ServiceInfo, &(Instance->Service->RestExServiceInfo), sizeof (EFI_REST_EX_SERVICE_INFO));\r
+\r
+ *RestExServiceInfo = ServiceInfo;\r
+\r
+ gBS->RestoreTPL (OldTpl);\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+ This function returns operational configuration of current EFI REST EX child instance.\r
+\r
+ This function returns the current configuration of EFI REST EX child instance. The format of\r
+ operational configuration depends on the implementation of EFI REST EX driver instance. For\r
+ example, HTTP-aware EFI REST EX driver instance uses EFI HTTP protocol as the undying protocol\r
+ to communicate with REST service. In this case, the type of configuration is\r
+ EFI_REST_EX_CONFIG_TYPE_HTTP returned from GetService(). EFI_HTTP_CONFIG_DATA is used as EFI REST\r
+ EX configuration format and returned to EFI REST client. User has to type cast RestExConfigData\r
+ to EFI_HTTP_CONFIG_DATA. For those non HTTP-aware REST EX driver instances, the type of configuration\r
+ is EFI_REST_EX_CONFIG_TYPE_UNSPECIFIC returned from GetService(). In this case, the format of\r
+ returning data could be non industrial. Instead, the format of configuration data is system/platform\r
+ specific definition such as BMC mechanism used in EFI REST EX driver instance. EFI REST client and\r
+ EFI REST EX driver instance have to refer to the specific system /platform spec which is out of UEFI scope.\r
+\r
+ @param[in] This This is the EFI_REST_EX_PROTOCOL instance.\r
+ @param[out] RestExConfigData Pointer to receive a pointer to EFI_REST_EX_CONFIG_DATA.\r
+ The memory allocated for configuration data should be freed\r
+ by caller. See Related Definitions for the details.\r
+\r
+ @retval EFI_SUCCESS EFI_REST_EX_CONFIG_DATA is returned in successfully.\r
+ @retval EFI_UNSUPPORTED This function is not supported in this REST EX Protocol driver instance.\r
+ @retval EFI_NOT_READY The configuration of this instance is not set yet. Configure() must be\r
+ executed and returns successfully prior to invoke this function.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+RedfishRestExGetModeData (\r
+ IN EFI_REST_EX_PROTOCOL *This,\r
+ OUT EFI_REST_EX_CONFIG_DATA *RestExConfigData\r
+ )\r
+{\r
+ return EFI_UNSUPPORTED;\r
+}\r
+\r
+/**\r
+ This function is used to configure EFI REST EX child instance.\r
+\r
+ This function is used to configure the setting of underlying protocol of REST EX child\r
+ instance. The type of configuration is according to the implementation of EFI REST EX\r
+ driver instance. For example, HTTP-aware EFI REST EX driver instance uses EFI HTTP protocol\r
+ as the undying protocol to communicate with REST service. The type of configuration is\r
+ EFI_REST_EX_CONFIG_TYPE_HTTP and RestExConfigData is the same format with EFI_HTTP_CONFIG_DATA.\r
+ Akin to HTTP configuration, REST EX child instance can be configure to use different HTTP\r
+ local access point for the data transmission. Multiple REST clients may use different\r
+ configuration of HTTP to distinguish themselves, such as to use the different TCP port.\r
+ For those non HTTP-aware REST EX driver instance, the type of configuration is\r
+ EFI_REST_EX_CONFIG_TYPE_UNSPECIFIC. RestExConfigData refers to the non industrial standard.\r
+ Instead, the format of configuration data is system/platform specific definition such as BMC.\r
+ In this case, EFI REST client and EFI REST EX driver instance have to refer to the specific\r
+ system/platform spec which is out of the UEFI scope. Besides GetService()function, no other\r
+ EFI REST EX functions can be executed by this instance until Configure()is executed and returns\r
+ successfully. All other functions must returns EFI_NOT_READY if this instance is not configured\r
+ yet. Set RestExConfigData to NULL means to put EFI REST EX child instance into the unconfigured\r
+ state.\r
+\r
+ @param[in] This This is the EFI_REST_EX_PROTOCOL instance.\r
+ @param[in] RestExConfigData Pointer to EFI_REST_EX_CONFIG_DATA. See Related Definitions in\r
+ GetModeData() protocol interface.\r
+\r
+ @retval EFI_SUCCESS EFI_REST_EX_CONFIG_DATA is set in successfully.\r
+ @retval EFI_DEVICE_ERROR Configuration for this REST EX child instance is failed with the given\r
+ EFI_REST_EX_CONFIG_DATA.\r
+ @retval EFI_UNSUPPORTED This function is not supported in this REST EX Protocol driver instance.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+RedfishRestExConfigure (\r
+ IN EFI_REST_EX_PROTOCOL *This,\r
+ IN EFI_REST_EX_CONFIG_DATA RestExConfigData\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_TPL OldTpl;\r
+ RESTEX_INSTANCE *Instance;\r
+\r
+ EFI_HTTP_CONFIG_DATA *HttpConfigData;\r
+\r
+ Status = EFI_SUCCESS;\r
+ HttpConfigData = NULL;\r
+\r
+ if (This == NULL) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
+\r
+ Instance = RESTEX_INSTANCE_FROM_THIS (This);\r
+\r
+ if (RestExConfigData == NULL) {\r
+ //\r
+ // Set RestExConfigData to NULL means to put EFI REST EX child instance into the unconfigured state.\r
+ //\r
+ HttpIoDestroyIo (&(Instance->HttpIo));\r
+\r
+ if (Instance->ConfigData != NULL) {\r
+ if (((EFI_REST_EX_HTTP_CONFIG_DATA *)Instance->ConfigData)->HttpConfigData.AccessPoint.IPv4Node != NULL) {\r
+ FreePool(((EFI_REST_EX_HTTP_CONFIG_DATA *)Instance->ConfigData)->HttpConfigData.AccessPoint.IPv4Node);\r
+ }\r
+ FreePool(Instance->ConfigData);\r
+ Instance->ConfigData = NULL;\r
+ }\r
+\r
+ Instance->State = RESTEX_STATE_UNCONFIGED;\r
+ } else {\r
+ HttpConfigData = &((EFI_REST_EX_HTTP_CONFIG_DATA *)RestExConfigData)->HttpConfigData;\r
+ Status = Instance->HttpIo.Http->Configure (Instance->HttpIo.Http, HttpConfigData);\r
+ if (EFI_ERROR (Status)) {\r
+ goto ON_EXIT;\r
+ }\r
+ Instance->HttpIo.Timeout = ((EFI_REST_EX_HTTP_CONFIG_DATA *)RestExConfigData)->SendReceiveTimeout;\r
+\r
+ Instance->ConfigData = AllocateZeroPool (sizeof (EFI_REST_EX_HTTP_CONFIG_DATA));\r
+ if (Instance->ConfigData == NULL) {\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ goto ON_EXIT;\r
+ }\r
+ CopyMem (Instance->ConfigData, RestExConfigData, sizeof (EFI_REST_EX_HTTP_CONFIG_DATA));\r
+ if (HttpConfigData->LocalAddressIsIPv6 == TRUE) {\r
+ ((EFI_REST_EX_HTTP_CONFIG_DATA *)Instance->ConfigData)->HttpConfigData.AccessPoint.IPv6Node = AllocateZeroPool (sizeof (EFI_HTTPv6_ACCESS_POINT));\r
+ if (((EFI_REST_EX_HTTP_CONFIG_DATA *)Instance->ConfigData)->HttpConfigData.AccessPoint.IPv6Node == NULL) {\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ goto ON_EXIT;\r
+ }\r
+ CopyMem (\r
+ ((EFI_REST_EX_HTTP_CONFIG_DATA *)Instance->ConfigData)->HttpConfigData.AccessPoint.IPv6Node,\r
+ HttpConfigData->AccessPoint.IPv6Node,\r
+ sizeof (EFI_HTTPv6_ACCESS_POINT)\r
+ );\r
+ } else {\r
+ ((EFI_REST_EX_HTTP_CONFIG_DATA *)Instance->ConfigData)->HttpConfigData.AccessPoint.IPv4Node = AllocateZeroPool (sizeof (EFI_HTTPv4_ACCESS_POINT));\r
+ if (((EFI_REST_EX_HTTP_CONFIG_DATA *)Instance->ConfigData)->HttpConfigData.AccessPoint.IPv4Node == NULL) {\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ goto ON_EXIT;\r
+ }\r
+ CopyMem (\r
+ ((EFI_REST_EX_HTTP_CONFIG_DATA *)Instance->ConfigData)->HttpConfigData.AccessPoint.IPv4Node,\r
+ HttpConfigData->AccessPoint.IPv4Node,\r
+ sizeof (EFI_HTTPv4_ACCESS_POINT)\r
+ );\r
+ }\r
+ Instance->State = RESTEX_STATE_CONFIGED;\r
+ }\r
+\r
+ON_EXIT:\r
+ gBS->RestoreTPL (OldTpl);\r
+ return Status;\r
+}\r
+\r
+/**\r
+ This function sends REST request to REST service and signal caller's event asynchronously when\r
+ the final response is received by REST EX Protocol driver instance.\r
+\r
+ The essential design of this function is to handle asynchronous send/receive implicitly according\r
+ to REST service asynchronous request mechanism. Caller will get the notification once the response\r
+ is returned from REST service.\r
+\r
+ @param[in] This This is the EFI_REST_EX_PROTOCOL instance.\r
+ @param[in] RequestMessage This is the HTTP request message sent to REST service. Set RequestMessage\r
+ to NULL to cancel the previous asynchronous request associated with the\r
+ corresponding RestExToken. See descriptions for the details.\r
+ @param[in] RestExToken REST EX token which REST EX Protocol instance uses to notify REST client\r
+ the status of response of asynchronous REST request. See related definition\r
+ of EFI_REST_EX_TOKEN.\r
+ @param[in] TimeOutInMilliSeconds The pointer to the timeout in milliseconds which REST EX Protocol driver\r
+ instance refers as the duration to drop asynchronous REST request. NULL\r
+ pointer means no timeout for this REST request. REST EX Protocol driver\r
+ signals caller's event with EFI_STATUS set to EFI_TIMEOUT in RestExToken\r
+ if REST EX Protocol can't get the response from REST service within\r
+ TimeOutInMilliSeconds.\r
+\r
+ @retval EFI_SUCCESS Asynchronous REST request is established.\r
+ @retval EFI_UNSUPPORTED This REST EX Protocol driver instance doesn't support asynchronous request.\r
+ @retval EFI_TIMEOUT Asynchronous REST request is not established and timeout is expired.\r
+ @retval EFI_ABORT Previous asynchronous REST request has been canceled.\r
+ @retval EFI_DEVICE_ERROR Otherwise, returns EFI_DEVICE_ERROR for other errors according to HTTP Status Code.\r
+ @retval EFI_NOT_READY The configuration of this instance is not set yet. Configure() must be executed\r
+ and returns successfully prior to invoke this function.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+RedfishRestExAyncSendReceive (\r
+ IN EFI_REST_EX_PROTOCOL *This,\r
+ IN EFI_HTTP_MESSAGE *RequestMessage OPTIONAL,\r
+ IN EFI_REST_EX_TOKEN *RestExToken,\r
+ IN UINTN *TimeOutInMilliSeconds OPTIONAL\r
+ )\r
+{\r
+ return EFI_UNSUPPORTED;\r
+}\r
+\r
+/**\r
+ This function sends REST request to a REST Event service and signals caller's event\r
+ token asynchronously when the URI resource change event is received by REST EX\r
+ Protocol driver instance.\r
+\r
+ The essential design of this function is to monitor event implicitly according to\r
+ REST service event service mechanism. Caller will get the notification if certain\r
+ resource is changed.\r
+\r
+ @param[in] This This is the EFI_REST_EX_PROTOCOL instance.\r
+ @param[in] RequestMessage This is the HTTP request message sent to REST service. Set RequestMessage\r
+ to NULL to cancel the previous event service associated with the corresponding\r
+ RestExToken. See descriptions for the details.\r
+ @param[in] RestExToken REST EX token which REST EX Protocol driver instance uses to notify REST client\r
+ the URI resource which monitored by REST client has been changed. See the related\r
+ definition of EFI_REST_EX_TOKEN in EFI_REST_EX_PROTOCOL.AsyncSendReceive().\r
+\r
+ @retval EFI_SUCCESS Asynchronous REST request is established.\r
+ @retval EFI_UNSUPPORTED This REST EX Protocol driver instance doesn't support asynchronous request.\r
+ @retval EFI_ABORT Previous asynchronous REST request has been canceled or event subscription has been\r
+ delete from service.\r
+ @retval EFI_DEVICE_ERROR Otherwise, returns EFI_DEVICE_ERROR for other errors according to HTTP Status Code.\r
+ @retval EFI_NOT_READY The configuration of this instance is not set yet. Configure() must be executed\r
+ and returns successfully prior to invoke this function.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+RedfishRestExEventService (\r
+ IN EFI_REST_EX_PROTOCOL *This,\r
+ IN EFI_HTTP_MESSAGE *RequestMessage OPTIONAL,\r
+ IN EFI_REST_EX_TOKEN *RestExToken\r
+ )\r
+{\r
+ return EFI_UNSUPPORTED;\r
+}\r
+\r