[edk2-devel] [PATCH] RedfishPkg/RedfishRestExDxe: Implementation of EFI REST EX Protocol

Abner Chang posted 1 patch 3 years, 4 months ago
Failed in applying to current master (apply log)
RedfishPkg/Redfish.fdf.inc                    |   1 +
RedfishPkg/RedfishComponents.dsc.inc          |   1 +
RedfishPkg/RedfishPkg.dsc                     |   4 +
RedfishPkg/RedfishRestExDxe/ComponentName.c   | 222 +++++
.../RedfishRestExDxe/RedfishRestExDriver.c    | 831 ++++++++++++++++++
.../RedfishRestExDxe/RedfishRestExDriver.h    | 650 ++++++++++++++
.../RedfishRestExDxe/RedfishRestExDxe.inf     |  63 ++
.../RedfishRestExDxe/RedfishRestExDxe.uni     |  16 +
.../RedfishRestExDxeExtra.uni                 |  15 +
.../RedfishRestExDxe/RedfishRestExImpl.c      | 157 ++++
.../RedfishRestExDxe/RedfishRestExInternal.h  | 611 +++++++++++++
.../RedfishRestExDxe/RedfishRestExProtocol.c  | 735 ++++++++++++++++
12 files changed, 3306 insertions(+)
create mode 100644 RedfishPkg/RedfishRestExDxe/ComponentName.c
create mode 100644 RedfishPkg/RedfishRestExDxe/RedfishRestExDriver.c
create mode 100644 RedfishPkg/RedfishRestExDxe/RedfishRestExDriver.h
create mode 100644 RedfishPkg/RedfishRestExDxe/RedfishRestExDxe.inf
create mode 100644 RedfishPkg/RedfishRestExDxe/RedfishRestExDxe.uni
create mode 100644 RedfishPkg/RedfishRestExDxe/RedfishRestExDxeExtra.uni
create mode 100644 RedfishPkg/RedfishRestExDxe/RedfishRestExImpl.c
create mode 100644 RedfishPkg/RedfishRestExDxe/RedfishRestExInternal.h
create mode 100644 RedfishPkg/RedfishRestExDxe/RedfishRestExProtocol.c
[edk2-devel] [PATCH] RedfishPkg/RedfishRestExDxe: Implementation of EFI REST EX Protocol
Posted by Abner Chang 3 years, 4 months ago
BZ#: 2908
https://bugzilla.tianocore.org/show_bug.cgi?id=2908

Implementation of EFI EX Protocol according to UEFI spec
2.8 Section 29.7.2 EFI REST EX Protocol.
This is the network stack based EFI REST EX protocol instance.

Signed-off-by: Jiaxin Wu <jiaxin.wu@intel.com>
Signed-off-by: Siyuan Fu <siyuan.fu@intel.com>
Signed-off-by: Fan Wang <fan.wang@intel.com>
Signed-off-by: Ting Ye <ting.ye@intel.com>
Signed-off-by: Abner Chang <abner.chang@hpe.com>

Cc: Jiaxin Wu <jiaxin.wu@intel.com>
Cc: Siyuan Fu <siyuan.fu@intel.com>
Cc: Fan Wang <fan.wang@intel.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Nickle Wang <nickle.wang@hpe.com>
Cc: Peter O'Hanley <peter.ohanley@hpe.com>
---
 RedfishPkg/Redfish.fdf.inc                    |   1 +
 RedfishPkg/RedfishComponents.dsc.inc          |   1 +
 RedfishPkg/RedfishPkg.dsc                     |   4 +
 RedfishPkg/RedfishRestExDxe/ComponentName.c   | 222 +++++
 .../RedfishRestExDxe/RedfishRestExDriver.c    | 831 ++++++++++++++++++
 .../RedfishRestExDxe/RedfishRestExDriver.h    | 650 ++++++++++++++
 .../RedfishRestExDxe/RedfishRestExDxe.inf     |  63 ++
 .../RedfishRestExDxe/RedfishRestExDxe.uni     |  16 +
 .../RedfishRestExDxeExtra.uni                 |  15 +
 .../RedfishRestExDxe/RedfishRestExImpl.c      | 157 ++++
 .../RedfishRestExDxe/RedfishRestExInternal.h  | 611 +++++++++++++
 .../RedfishRestExDxe/RedfishRestExProtocol.c  | 735 ++++++++++++++++
 12 files changed, 3306 insertions(+)
 create mode 100644 RedfishPkg/RedfishRestExDxe/ComponentName.c
 create mode 100644 RedfishPkg/RedfishRestExDxe/RedfishRestExDriver.c
 create mode 100644 RedfishPkg/RedfishRestExDxe/RedfishRestExDriver.h
 create mode 100644 RedfishPkg/RedfishRestExDxe/RedfishRestExDxe.inf
 create mode 100644 RedfishPkg/RedfishRestExDxe/RedfishRestExDxe.uni
 create mode 100644 RedfishPkg/RedfishRestExDxe/RedfishRestExDxeExtra.uni
 create mode 100644 RedfishPkg/RedfishRestExDxe/RedfishRestExImpl.c
 create mode 100644 RedfishPkg/RedfishRestExDxe/RedfishRestExInternal.h
 create mode 100644 RedfishPkg/RedfishRestExDxe/RedfishRestExProtocol.c

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



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#68377): https://edk2.groups.io/g/devel/message/68377
Mute This Topic: https://groups.io/mt/78773779/1787277
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org]
-=-=-=-=-=-=-=-=-=-=-=-


Re: [edk2-devel] [PATCH] RedfishPkg/RedfishRestExDxe: Implementation of EFI REST EX Protocol
Posted by Nickle Wang 3 years, 4 months ago
Reviewed-by: Nickle Wang <nickle.wang@hpe.com>


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



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#68628): https://edk2.groups.io/g/devel/message/68628
Mute This Topic: https://groups.io/mt/78773779/1787277
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org]
-=-=-=-=-=-=-=-=-=-=-=-