/** @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;
}

