/** @file

  The implementation of EFI Redfidh Discover Protocol.

  (C) Copyright 2021 Hewlett Packard Enterprise Development LP<BR>
  Copyright (c) 2022, AMD Incorporated. All rights reserved.

  SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "RedfishDiscoverInternal.h"

LIST_ENTRY           mRedfishDiscoverList;
LIST_ENTRY           mRedfishInstanceList;
EFI_SMBIOS_PROTOCOL  *mSmbios = NULL;

UINTN       mNumNetworkInterface = 0;
UINTN       mNumRestExInstance   = 0;
LIST_ENTRY  mEfiRedfishDiscoverNetworkInterface;
LIST_ENTRY  mEfiRedfishDiscoverRestExInstance;

EFI_GUID  mRedfishDiscoverTcp4InstanceGuid   = EFI_REDFISH_DISCOVER_TCP4_INSTANCE_GUID;
EFI_GUID  mRedfishDiscoverTcp6InstanceGuid   = EFI_REDFISH_DISCOVER_TCP6_INSTANCE_GUID;
EFI_GUID  mRedfishDiscoverRestExInstanceGuid = EFI_REDFISH_DISCOVER_REST_EX_INSTANCE_GUID;

EFI_STATUS
EFIAPI
Tcp4GetSubnetInfo (
  IN EFI_HANDLE                                       ImageHandle,
  IN EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL  *Instance
  );

EFI_STATUS
EFIAPI
Tcp6GetSubnetInfo (
  IN EFI_HANDLE                                       ImageHandle,
  IN EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL  *Instance
  );

static REDFISH_DISCOVER_REQUIRED_PROTOCOL  gRequiredProtocol[] = {
  {
    ProtocolTypeTcp4,
    L"TCP4 Service Binding Protocol",
    &gEfiTcp4ProtocolGuid,
    &gEfiTcp4ServiceBindingProtocolGuid,
    &mRedfishDiscoverTcp4InstanceGuid,
    Tcp4GetSubnetInfo
  },
  {
    ProtocolTypeTcp6,
    L"TCP6 Service Binding Protocol",
    &gEfiTcp6ProtocolGuid,
    &gEfiTcp6ServiceBindingProtocolGuid,
    &mRedfishDiscoverTcp6InstanceGuid,
    Tcp6GetSubnetInfo
  },
  {
    ProtocolTypeRestEx,
    L"REST EX Service Binding Protocol",
    &gEfiRestExProtocolGuid,
    &gEfiRestExServiceBindingProtocolGuid,
    &mRedfishDiscoverRestExInstanceGuid,
    NULL
  }
};

/**
  This function creates REST EX instance for the found Resfish service.
  by known owner handle.

  @param[in]    Instance        EFI_REDFISH_DISCOVERED_INTERNAL_INSTANCE
  @param[in]    Token           Client token.

  @retval NULL  Instance not found.
  @retval EFI_REDFISH_DISCOVERED_INTERNAL_INSTANCE The instance owned by this owner.

**/
EFI_STATUS
CreateRestExInstance (
  IN EFI_REDFISH_DISCOVERED_INTERNAL_INSTANCE  *Instance,
  IN EFI_REDFISH_DISCOVERED_TOKEN              *Token
  )
{
  EFI_STATUS  Status;

  Status = RestExLibCreateChild (
             Instance->Owner,
             FixedPcdGetBool (PcdRedfishDiscoverAccessModeInBand) ? EfiRestExServiceInBandAccess : EfiRestExServiceOutOfBandAccess,
             EfiRestExConfigHttp,
             EfiRestExServiceRedfish,
             &Token->DiscoverList.RedfishInstances->Information.RedfishRestExHandle
             );
  return Status;
}

/**
  This function gets EFI_REDFISH_DISCOVERED_INTERNAL_INSTANCE
  by known owner handle.

  @param[in]    ImageHandle             Image handle owns EFI_REDFISH_DISCOVERED_INTERNAL_INSTANCE.
  @param[in]    TargetNetworkInterface  Target network interface used by this EFI_REDFISH_DISCOVERED_INTERNAL_INSTANCE.
  @param[in]    DiscoverFlags           EFI_REDFISH_DISCOVER_FLAG

  @retval NULL  Instance not found.
  @retval EFI_REDFISH_DISCOVERED_INTERNAL_INSTANCE The instance owned by this owner.

**/
EFI_REDFISH_DISCOVERED_INTERNAL_INSTANCE *
GetInstanceByOwner (
  IN EFI_HANDLE                                       ImageHandle,
  IN EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL  *TargetNetworkInterface,
  IN EFI_REDFISH_DISCOVER_FLAG                        DiscoverFlags
  )
{
  EFI_REDFISH_DISCOVERED_INTERNAL_INSTANCE  *ThisInstance;

  if (IsListEmpty (&mRedfishDiscoverList)) {
    return NULL;
  }

  ThisInstance =
    (EFI_REDFISH_DISCOVERED_INTERNAL_INSTANCE *)GetFirstNode (&mRedfishDiscoverList);
  while (TRUE) {
    if ((ThisInstance->Owner == ImageHandle) &&
        (ThisInstance->DiscoverFlags == DiscoverFlags) &&
        (ThisInstance->NetworkInterface == TargetNetworkInterface))
    {
      return ThisInstance;
    }

    if (IsNodeAtEnd (&mRedfishDiscoverList, &ThisInstance->Entry)) {
      break;
    }

    ThisInstance =
      (EFI_REDFISH_DISCOVERED_INTERNAL_INSTANCE *)GetNextNode (&mRedfishDiscoverList, &ThisInstance->Entry);
  }

  return NULL;
}

/**
  This function gets the subnet information of this TCP4 instance.

  @param[in]            ImageHandle  EFI handle with this image.
  @param[in]            Instance  Instance of Network interface.
  @retval EFI_STATUS    Get subnet information successfully.
  @retval Otherwise     Fail to get subnet information.
**/
EFI_STATUS
EFIAPI
Tcp4GetSubnetInfo (
  IN EFI_HANDLE                                       ImageHandle,
  IN EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL  *Instance
  )
{
  EFI_STATUS            Status;
  EFI_TCP4_PROTOCOL     *Tcp4;
  EFI_TCP4_CONFIG_DATA  Tcp4CfgData;
  EFI_TCP4_OPTION       Tcp4Option;
  EFI_IP4_MODE_DATA     IpModedata;
  UINT8                 SubnetMaskIndex;
  UINT8                 BitMask;
  UINT8                 PrefixLength;
  BOOLEAN               GotPrefixLength;

  if (Instance == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  Tcp4 = (EFI_TCP4_PROTOCOL *)Instance->NetworkInterfaceProtocolInfo.NetworkProtocolInterface;

  ZeroMem ((VOID *)&Tcp4CfgData, sizeof (EFI_TCP4_CONFIG_DATA));
  ZeroMem ((VOID *)&Tcp4Option, sizeof (EFI_TCP4_OPTION));
  // Give a local host IP address just for getting subnet information.
  Tcp4CfgData.AccessPoint.UseDefaultAddress     = TRUE;
  Tcp4CfgData.AccessPoint.RemoteAddress.Addr[0] = 127;
  Tcp4CfgData.AccessPoint.RemoteAddress.Addr[1] = 0;
  Tcp4CfgData.AccessPoint.RemoteAddress.Addr[2] = 0;
  Tcp4CfgData.AccessPoint.RemoteAddress.Addr[3] = 1;
  Tcp4CfgData.AccessPoint.RemotePort            = 80;
  Tcp4CfgData.AccessPoint.ActiveFlag            = TRUE;

  Tcp4CfgData.ControlOption    = &Tcp4Option;
  Tcp4Option.ReceiveBufferSize = 65535;
  Tcp4Option.SendBufferSize    = 65535;
  Tcp4Option.MaxSynBackLog     = 5;
  Tcp4Option.ConnectionTimeout = 60;
  Tcp4Option.DataRetries       = 12;
  Tcp4Option.FinTimeout        = 2;
  Tcp4Option.KeepAliveProbes   = 6;
  Tcp4Option.KeepAliveTime     = 7200;
  Tcp4Option.KeepAliveInterval = 30;
  Tcp4Option.EnableNagle       = TRUE;
  Status                       = Tcp4->Configure (Tcp4, &Tcp4CfgData);
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "%a: Can't get subnet information\n", __FUNCTION__));
    return Status;
  }

  Status = Tcp4->GetModeData (Tcp4, NULL, NULL, &IpModedata, NULL, NULL);
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "%a: Can't get IP mode data information\n", __FUNCTION__));
    return Status;
  }

  IP4_COPY_ADDRESS (&Instance->SubnetMask, &IpModedata.ConfigData.SubnetMask);
  Instance->SubnetAddr.v4.Addr[0] = IpModedata.ConfigData.StationAddress.Addr[0] & Instance->SubnetMask.v4.Addr[0];
  Instance->SubnetAddr.v4.Addr[1] = IpModedata.ConfigData.StationAddress.Addr[1] & Instance->SubnetMask.v4.Addr[1];
  Instance->SubnetAddr.v4.Addr[2] = IpModedata.ConfigData.StationAddress.Addr[2] & Instance->SubnetMask.v4.Addr[2];
  Instance->SubnetAddr.v4.Addr[3] = IpModedata.ConfigData.StationAddress.Addr[3] & Instance->SubnetMask.v4.Addr[3];
  //
  // Calculate the subnet mask prefix.
  //
  GotPrefixLength = FALSE;
  PrefixLength    = 0;
  SubnetMaskIndex = 0;
  while (GotPrefixLength == FALSE && SubnetMaskIndex < 4) {
    BitMask = 0x80;
    while (BitMask != 0) {
      if ((Instance->SubnetMask.v4.Addr[SubnetMaskIndex] & BitMask) != 0) {
        PrefixLength++;
      } else {
        GotPrefixLength = TRUE;
        break;
      }

      BitMask = BitMask >> 1;
    }

    SubnetMaskIndex++;
  }

  Instance->SubnetPrefixLength = PrefixLength;
  return EFI_SUCCESS;
}

/**
  This function gets the subnet information of this TCP6 instance.

  @param[in]            ImageHandle  EFI handle with this image.
  @param[in]            Instance  Instance of Network interface.
  @retval EFI_STATUS    Get subnet information successfully.
  @retval Otherwise     Fail to get subnet information.
**/
EFI_STATUS
EFIAPI
Tcp6GetSubnetInfo (
  IN EFI_HANDLE                                       ImageHandle,
  IN EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL  *Instance
  )
{
  EFI_STATUS         Status;
  EFI_TCP6_PROTOCOL  *Tcp6;
  EFI_IP6_MODE_DATA  IpModedata;

  if (Instance == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  Tcp6 = (EFI_TCP6_PROTOCOL *)Instance->NetworkInterfaceProtocolInfo.NetworkProtocolInterface;

  ZeroMem ((VOID *)&IpModedata, sizeof (EFI_IP6_MODE_DATA));
  Status = Tcp6->GetModeData (Tcp6, NULL, NULL, &IpModedata, NULL, NULL);
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "%a: Can't get IP mode data information\n", __FUNCTION__));
    return Status;
  }

  if (IpModedata.AddressCount == 0) {
    DEBUG ((DEBUG_INFO, "%a: No IPv6 address configured.\n", __FUNCTION__));
  }

  if (Instance->SubnetAddrInfoIPv6 != NULL) {
    FreePool (Instance->SubnetAddrInfoIPv6);
  }

  Instance->SubnetAddrInfoIPv6 = AllocateZeroPool (IpModedata.AddressCount * sizeof (EFI_IP6_ADDRESS_INFO));
  if (Instance->SubnetAddrInfoIPv6 == NULL) {
    DEBUG ((DEBUG_ERROR, "%a: Failed to allocate memory for IPv6 subnet address information\n", __FUNCTION__));
    return EFI_OUT_OF_RESOURCES;
  }

  Instance->SubnetAddrInfoIPv6Number = IpModedata.AddressCount;
  if ((IpModedata.AddressCount != 0) && (IpModedata.AddressList != NULL)) {
    CopyMem (
      (VOID *)Instance->SubnetAddrInfoIPv6,
      (VOID *)&IpModedata.AddressList,
      IpModedata.AddressCount * sizeof (EFI_IP6_ADDRESS_INFO)
      );
    FreePool (IpModedata.AddressList);
  }

  return EFI_SUCCESS;
}

/**
  This function searches EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL
  instance with the given  EFI_REDFISH_DISCOVER_NETWORK_INTERFACE.

  @param[in] TargetNetworkInterface  EFI_REDFISH_DISCOVER_NETWORK_INTERFACE.
                                     NULL for all EFI_REDFISH_DISCOVER_NETWORK_INTERFACEs.

  @retval Non-NULL  EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL is returned.
  @retval NULL      Non of EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL instance is returned.
**/
EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *
GetTargetNetworkInterfaceInternal (
  IN EFI_REDFISH_DISCOVER_NETWORK_INTERFACE  *TargetNetworkInterface
  )
{
  EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL  *ThisNetworkInterface;

  ThisNetworkInterface = (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *)GetFirstNode (&mEfiRedfishDiscoverNetworkInterface);
  while (TRUE) {
    if (CompareMem ((VOID *)&ThisNetworkInterface->MacAddress, &TargetNetworkInterface->MacAddress, ThisNetworkInterface->HwAddressSize) == 0) {
      return ThisNetworkInterface;
    }

    if (IsNodeAtEnd (&mEfiRedfishDiscoverNetworkInterface, &ThisNetworkInterface->Entry)) {
      return NULL;
    }

    ThisNetworkInterface = (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *)GetNextNode (&mEfiRedfishDiscoverNetworkInterface, &ThisNetworkInterface->Entry);
  }

  return NULL;
}

/**
  This function searches EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL
  instance with the given  Controller handle.

  @param[in] ControllerHandle  The controller handle associated with network interface.

  @retval Non-NULL  EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL is returned.
  @retval NULL      Non of EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL instance is returned.
**/
EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *
GetTargetNetworkInterfaceInternalByController (
  IN EFI_HANDLE  ControllerHandle
  )
{
  EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL  *ThisNetworkInterface;

  ThisNetworkInterface = (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *)GetFirstNode (&mEfiRedfishDiscoverNetworkInterface);
  while (TRUE) {
    if (ThisNetworkInterface->OpenDriverControllerHandle == ControllerHandle) {
      return ThisNetworkInterface;
    }

    if (IsNodeAtEnd (&mEfiRedfishDiscoverNetworkInterface, &ThisNetworkInterface->Entry)) {
      return NULL;
    }

    ThisNetworkInterface = (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *)GetNextNode (&mEfiRedfishDiscoverNetworkInterface, &ThisNetworkInterface->Entry);
  }

  return NULL;
}

/**
  This function validate if target network interface is ready for discovering
  Redfish service.

  @param[in] TargetNetworkInterface  EFI_REDFISH_DISCOVER_NETWORK_INTERFACE.
                                     NULL for all EFI_REDFISH_DISCOVER_NETWORK_INTERFACEs.
  @param[in] Flags                   EFI_REDFISH_DISCOVER_FLAG

  @retval EFI_SUCCESS     Target network interface is ready to use.
  @retval EFI_UNSUPPORTED Target network interface is not ready to use.
**/
EFI_STATUS
ValidateTargetNetworkInterface (
  IN EFI_REDFISH_DISCOVER_NETWORK_INTERFACE  *TargetNetworkInterface,
  IN EFI_REDFISH_DISCOVER_FLAG               Flags
  )
{
  EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL  *ThisNetworkInterface;

  if (IsListEmpty (&mEfiRedfishDiscoverNetworkInterface) && (TargetNetworkInterface == NULL)) {
    return EFI_UNSUPPORTED;
  }

  if (TargetNetworkInterface == NULL) {
    return EFI_SUCCESS; // Return EFI_SUCCESS if no network interface is specified.
  }

  ThisNetworkInterface = (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *)GetFirstNode (&mEfiRedfishDiscoverNetworkInterface);
  while (TRUE) {
    if (CompareMem ((VOID *)&ThisNetworkInterface->MacAddress, &TargetNetworkInterface->MacAddress, ThisNetworkInterface->HwAddressSize) == 0) {
      break;
    }

    if (IsNodeAtEnd (&mEfiRedfishDiscoverNetworkInterface, &ThisNetworkInterface->Entry)) {
      return EFI_UNSUPPORTED;
    }

    ThisNetworkInterface = (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *)GetNextNode (&mEfiRedfishDiscoverNetworkInterface, &ThisNetworkInterface->Entry);
  }

  if ((Flags & EFI_REDFISH_DISCOVER_SSDP) != 0) {
    // Validate if UDP4/6 is supported on the given network interface.
    // SSDP is not supported.

    return EFI_SUCCESS;
  }

  if (ThisNetworkInterface->NetworkInterfaceProtocolInfo.ProtocolControllerHandle == NULL) {
    return EFI_UNSUPPORTED; // The required protocol on this network interface is not found.
  }

  return EFI_SUCCESS;
}

/**
  This function returns number of network interface instance.

  @retval UINTN  Number of network interface instances.
**/
UINTN
NumberOfNetworkInterface (
  VOID
  )
{
  UINTN                                            Num;
  EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL  *ThisNetworkInterface;

  if (IsListEmpty (&mEfiRedfishDiscoverNetworkInterface)) {
    return 0;
  }

  Num                  = 1;
  ThisNetworkInterface = (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *)GetFirstNode (&mEfiRedfishDiscoverNetworkInterface);
  while (TRUE) {
    if (IsNodeAtEnd (&mEfiRedfishDiscoverNetworkInterface, &ThisNetworkInterface->Entry)) {
      break;
    }

    ThisNetworkInterface = (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *)GetNextNode (&mEfiRedfishDiscoverNetworkInterface, &ThisNetworkInterface->Entry);
    Num++;
  }

  return Num;
}

/**
  This function checks the  IP version supported on this
  netwoek interface.

  @param[in]    ThisNetworkInterface   EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL

  @retval TRUE  Is IPv6, otherwise IPv4.

**/
BOOLEAN
CheckIsIpVersion6 (
  IN EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL  *ThisNetworkInterface
  )
{
  if (ThisNetworkInterface->NetworkProtocolType == ProtocolTypeTcp6) {
    return TRUE;
  }

  return FALSE;
}

/**
  This function discover Redfish service through SMBIOS host interface.

  @param[in]    Instance     EFI_REDFISH_DISCOVERED_INTERNAL_INSTANCE

  @retval EFI_SUCCESS        Redfish service is discovered through SMBIOS Host interface.
  @retval Others             Fail to discover Redfish service throught SMBIOS host interface

**/
EFI_STATUS
DiscoverRedfishHostInterface (
  IN EFI_REDFISH_DISCOVERED_INTERNAL_INSTANCE  *Instance
  )
{
  EFI_STATUS                     Status;
  REDFISH_OVER_IP_PROTOCOL_DATA  *Data;
  REDFISH_INTERFACE_DATA         *DeviceDescriptor;
  CHAR8                          UuidStr[sizeof "00000000-0000-0000-0000-000000000000" + 1];
  CHAR16                         Ipv6Str[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff" + 1];
  CHAR8                          RedfishServiceLocateStr[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff" + 1];
  UINTN                          StrSize;
  UINTN                          MacCompareStstus;
  BOOLEAN                        IsHttps;

  Data             = NULL;
  DeviceDescriptor = NULL;

  if (mSmbios == NULL) {
    Status = gBS->LocateProtocol (&gEfiSmbiosProtocolGuid, NULL, (VOID **)&mSmbios);
    if (EFI_ERROR (Status)) {
      return Status;
    }
  }

  Status = RedfishGetHostInterfaceProtocolData (mSmbios, &DeviceDescriptor, &Data); // Search for SMBIOS type 42h
  if (!EFI_ERROR (Status) && (Data != NULL) && (DeviceDescriptor != NULL)) {
    //
    // Chceck if we can reach out Redfish service using this network interface.
    // Check with MAC address using Device Descroptor Data Device Type 04 and Type 05.
    // Those two types of Redfish host interface device has MAC information.
    //
    if (DeviceDescriptor->DeviceType == REDFISH_HOST_INTERFACE_DEVICE_TYPE_PCI_PCIE_V2) {
      MacCompareStstus = CompareMem (&Instance->NetworkInterface->MacAddress, &DeviceDescriptor->DeviceDescriptor.PciPcieDeviceV2.MacAddress, 6);
    } else if (DeviceDescriptor->DeviceType == REDFISH_HOST_INTERFACE_DEVICE_TYPE_USB_V2) {
      MacCompareStstus = CompareMem (&Instance->NetworkInterface->MacAddress, &DeviceDescriptor->DeviceDescriptor.UsbDeviceV2.MacAddress, 6);
    } else {
      return EFI_UNSUPPORTED;
    }

    if (MacCompareStstus != 0) {
      return EFI_UNSUPPORTED;
    }

    if (Data->RedfishServiceIpAddressFormat == 1) {
      IP4_COPY_ADDRESS ((VOID *)&Instance->TargetIpAddress.v4, (VOID *)Data->RedfishServiceIpAddress);
    } else {
      IP6_COPY_ADDRESS ((VOID *)&Instance->TargetIpAddress.v6, (VOID *)Data->RedfishServiceIpAddress);
    }

    if (Instance->HostIntfValidation) {
      DEBUG ((DEBUG_ERROR, "%a:Send UPnP unicast SSDP to validate this Redfish Host Interface is not supported.\n", __FUNCTION__));
      Status = EFI_UNSUPPORTED;
    } else {
      //
      // Add this istance to list without detial information of Redfish
      // service.
      //
      IsHttps = FALSE;
      if (Data->RedfishServiceIpPort == 443) {
        IsHttps = TRUE;
      }

      StrSize = sizeof (UuidStr);
      AsciiSPrint (UuidStr, StrSize, "%g", &Data->ServiceUuid);
      //
      // Generate Redfish service location string.
      //
      if (Data->RedfishServiceIpAddressFormat == REDFISH_HOST_INTERFACE_HOST_IP_ADDRESS_FORMAT_IP6) {
        NetLibIp6ToStr ((IPv6_ADDRESS *)&Data->RedfishServiceIpAddress, Ipv6Str, sizeof (Ipv6Str));
        if ((Data->RedfishServiceIpPort == 0) || (IsHttps == TRUE)) {
          AsciiSPrintUnicodeFormat (
            RedfishServiceLocateStr,
            sizeof (RedfishServiceLocateStr),
            L"%s",
            Ipv6Str
            );
        } else {
          AsciiSPrintUnicodeFormat (
            RedfishServiceLocateStr,
            sizeof (RedfishServiceLocateStr),
            L"[%s]:%d",
            Ipv6Str,
            Data->RedfishServiceIpPort
            );
        }
      } else {
        if ((Data->RedfishServiceIpPort == 0) || (IsHttps == TRUE)) {
          AsciiSPrint (
            RedfishServiceLocateStr,
            sizeof (RedfishServiceLocateStr),
            "%d.%d.%d.%d",
            Data->RedfishServiceIpAddress[0],
            Data->RedfishServiceIpAddress[1],
            Data->RedfishServiceIpAddress[2],
            Data->RedfishServiceIpAddress[3]
            );
        } else {
          AsciiSPrint (
            RedfishServiceLocateStr,
            sizeof (RedfishServiceLocateStr),
            "%d.%d.%d.%d:%d",
            Data->RedfishServiceIpAddress[0],
            Data->RedfishServiceIpAddress[1],
            Data->RedfishServiceIpAddress[2],
            Data->RedfishServiceIpAddress[3],
            Data->RedfishServiceIpPort
            );
        }
      }

      Status = AddAndSignalNewRedfishService (
                 Instance,
                 NULL,
                 RedfishServiceLocateStr,
                 UuidStr,
                 NULL,
                 NULL,
                 NULL,
                 NULL,
                 IsHttps
                 );
    }
  }

  return Status;
}

/**
  The function adds a new found Redfish service to internal list and
  notify client.

  @param[in]  Instance              EFI_REDFISH_DISCOVERED_INTERNAL_INSTANCE.
  @param[in]  RedfishVersion        Redfish version.
  @param[in]  RedfishLocation       Redfish location.
  @param[in]  Uuid                  Service UUID string.
  @param[in]  Os                    OS string.
  @param[in]  OsVer                 OS version string.
  @param[in]  Product               Product string.
  @param[in]  ProductVer            Product verison string.
  @param[in]  UseHttps              Redfish service requires secured connection.
  @retval EFI_SUCCESS               Redfish service is added to list successfully.

**/
EFI_STATUS
AddAndSignalNewRedfishService (
  IN EFI_REDFISH_DISCOVERED_INTERNAL_INSTANCE  *Instance,
  IN UINTN                                     *RedfishVersion OPTIONAL,
  IN CHAR8                                     *RedfishLocation OPTIONAL,
  IN CHAR8                                     *Uuid  OPTIONAL,
  IN CHAR8                                     *Os  OPTIONAL,
  IN CHAR8                                     *OsVer  OPTIONAL,
  IN CHAR8                                     *Product  OPTIONAL,
  IN CHAR8                                     *ProductVer  OPTIONAL,
  IN BOOLEAN                                   UseHttps
  )
{
  BOOLEAN                                          NewFound;
  BOOLEAN                                          InfoRefresh;
  BOOLEAN                                          RestExOpened;
  BOOLEAN                                          DeleteRestEx;
  EFI_STATUS                                       Status;
  EFI_REDFISH_DISCOVERED_INTERNAL_LIST             *DiscoveredList;
  EFI_REDFISH_DISCOVERED_INSTANCE                  *DiscoveredInstance;
  CHAR16                                           *Char16Uuid;
  EFI_REST_EX_PROTOCOL                             *RestEx;
  EFI_REST_EX_HTTP_CONFIG_DATA                     *RestExHttpConfigData;
  EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL  *NetworkInterface;

  NewFound     = TRUE;
  InfoRefresh  = FALSE;
  Char16Uuid   = NULL;
  RestExOpened = FALSE;
  DeleteRestEx = FALSE;

  DEBUG ((DEBUG_INFO, "%a:Add this instance to Redfish instance list.\n", __FUNCTION__));

  if (Uuid != NULL) {
    Char16Uuid = (CHAR16 *)AllocateZeroPool (AsciiStrSize ((const CHAR8 *)Uuid) * sizeof (CHAR16));
    AsciiStrToUnicodeStrS ((const CHAR8 *)Uuid, Char16Uuid, AsciiStrSize ((const CHAR8 *)Uuid) * sizeof (CHAR16));
  }

  DiscoveredList       = NULL;
  DiscoveredInstance   = NULL;
  RestExHttpConfigData = NULL;

  NetworkInterface = Instance->NetworkInterface;
  if (!IsListEmpty (&mRedfishInstanceList)) {
    //
    // Is this a duplicate redfish service.
    //
    DiscoveredList = (EFI_REDFISH_DISCOVERED_INTERNAL_LIST *)GetFirstNode (&mRedfishInstanceList);
    NewFound       = FALSE;
    do {
      if ((Char16Uuid == NULL) || (DiscoveredList->Instance->Information.Uuid == NULL)) {
        //
        // Check if this Redfish instance already found using IP addrress.
        //
        if (!CheckIsIpVersion6 (NetworkInterface)) {
          if (CompareMem (
                (VOID *)&Instance->TargetIpAddress.v4,
                (VOID *)&DiscoveredList->Instance->Information.RedfishHostIpAddress.v4,
                sizeof (EFI_IPv4_ADDRESS)
                ) == 0)
          {
            DiscoveredInstance = DiscoveredList->Instance;
            if ((DiscoveredList->Instance->Information.Uuid == NULL) &&
                (Char16Uuid != NULL))
            {
              InfoRefresh        = TRUE;
              DiscoveredInstance = DiscoveredList->Instance;
              DEBUG ((DEBUG_INFO, "*** This Redfish Service information refresh ***\n"));
            }

            break;
          }
        } else {
          if (CompareMem (
                (VOID *)&Instance->TargetIpAddress.v6,
                (VOID *)&DiscoveredList->Instance->Information.RedfishHostIpAddress.v6,
                sizeof (EFI_IPv6_ADDRESS)
                ) == 0)
          {
            DiscoveredInstance = DiscoveredList->Instance;
            break;
          }
        }
      } else {
        //
        // Check if this Redfish instance already found using UUID.
        //
        if (StrCmp ((const CHAR16 *)Char16Uuid, (const CHAR16 *)DiscoveredList->Instance->Information.Uuid) == 0) {
          DiscoveredInstance = DiscoveredList->Instance;
          break;
        }
      }

      if (IsNodeAtEnd (&mRedfishInstanceList, &DiscoveredList->NextInstance)) {
        NewFound = TRUE;
        break;
      }

      DiscoveredList = (EFI_REDFISH_DISCOVERED_INTERNAL_LIST *)GetNextNode (&mRedfishInstanceList, &DiscoveredList->NextInstance);
    } while (TRUE);
  }

  if (NewFound || InfoRefresh) {
    if (!InfoRefresh) {
      DiscoveredList = (EFI_REDFISH_DISCOVERED_INTERNAL_LIST *)AllocateZeroPool (sizeof (EFI_REDFISH_DISCOVERED_INTERNAL_LIST));
      if (DiscoveredList == NULL) {
        return EFI_OUT_OF_RESOURCES;
      }

      InitializeListHead (&DiscoveredList->NextInstance);
      DiscoveredInstance = (EFI_REDFISH_DISCOVERED_INSTANCE *)AllocateZeroPool (sizeof (EFI_REDFISH_DISCOVERED_INSTANCE));
      if (DiscoveredInstance == NULL) {
        FreePool ((VOID *)DiscoveredList);
        return EFI_OUT_OF_RESOURCES;
      }
    }

    DEBUG ((DEBUG_INFO, "*** Redfish Service Information ***\n"));

    DiscoveredInstance->Information.UseHttps = UseHttps;
    if (RedfishVersion != NULL) {
      DiscoveredInstance->Information.RedfishVersion = *RedfishVersion;
      DEBUG ((DEBUG_INFO, "Redfish service version: %d.\n", DiscoveredInstance->Information.RedfishVersion));
    }

    if (RedfishLocation != NULL) {
      DiscoveredInstance->Information.Location = (CHAR16 *)AllocatePool (AsciiStrSize ((const CHAR8 *)RedfishLocation) * sizeof (CHAR16));
      AsciiStrToUnicodeStrS ((const CHAR8 *)RedfishLocation, DiscoveredInstance->Information.Location, AsciiStrSize ((const CHAR8 *)RedfishLocation) * sizeof (CHAR16));
      DEBUG ((DEBUG_INFO, "Redfish service location: %s.\n", DiscoveredInstance->Information.Location));
    }

    if (Uuid != NULL) {
      DiscoveredInstance->Information.Uuid = (CHAR16 *)AllocatePool (AsciiStrSize ((const CHAR8 *)Uuid) * sizeof (CHAR16));
      AsciiStrToUnicodeStrS ((const CHAR8 *)Uuid, DiscoveredInstance->Information.Uuid, AsciiStrSize ((const CHAR8 *)Uuid) * sizeof (CHAR16));
      DEBUG ((DEBUG_INFO, "Service UUID: %s.\n", DiscoveredInstance->Information.Uuid));
    }

    if (Os != NULL) {
      DiscoveredInstance->Information.Os = (CHAR16 *)AllocatePool (AsciiStrSize ((const CHAR8 *)Os) * sizeof (CHAR16));
      AsciiStrToUnicodeStrS ((const CHAR8 *)Os, DiscoveredInstance->Information.Os, AsciiStrSize ((const CHAR8 *)Os) * sizeof (CHAR16));
      DEBUG ((DEBUG_INFO, "Redfish service OS: %s, Version:%s.\n", DiscoveredInstance->Information.Os, DiscoveredInstance->Information.OsVersion));
    }

    if (OsVer != NULL) {
      DiscoveredInstance->Information.OsVersion = (CHAR16 *)AllocatePool (AsciiStrSize ((const CHAR8 *)OsVer) * sizeof (CHAR16));
      AsciiStrToUnicodeStrS ((const CHAR8 *)OsVer, DiscoveredInstance->Information.OsVersion, AsciiStrSize ((const CHAR8 *)OsVer) * sizeof (CHAR16));
    }

    if ((Product != NULL) && (ProductVer != NULL)) {
      DiscoveredInstance->Information.Product = (CHAR16 *)AllocatePool (AsciiStrSize ((const CHAR8 *)Product) * sizeof (CHAR16));
      AsciiStrToUnicodeStrS ((const CHAR8 *)Product, DiscoveredInstance->Information.Product, AsciiStrSize ((const CHAR8 *)Product) * sizeof (CHAR16));
      DiscoveredInstance->Information.ProductVer = (CHAR16 *)AllocatePool (AsciiStrSize ((const CHAR8 *)ProductVer) * sizeof (CHAR16));
      AsciiStrToUnicodeStrS ((const CHAR8 *)ProductVer, DiscoveredInstance->Information.ProductVer, AsciiStrSize ((const CHAR8 *)ProductVer) * sizeof (CHAR16));
      DEBUG ((DEBUG_INFO, "Redfish service product: %s, Version:%s.\n", DiscoveredInstance->Information.Product, DiscoveredInstance->Information.ProductVer));
    }

    if (RedfishLocation == NULL) {
      // This is the Redfish reported from SMBIOS 42h
      // without validation.

      IP4_COPY_ADDRESS ((VOID *)&DiscoveredInstance->Information.RedfishHostIpAddress.v4, (VOID *)&Instance->TargetIpAddress.v4);
    }

    if (!InfoRefresh) {
      DiscoveredList->Instance = DiscoveredInstance;
      InsertTailList (&mRedfishInstanceList, &DiscoveredList->NextInstance);
    }

    DiscoveredInstance->Status = EFI_SUCCESS;
  } else {
    if (DiscoveredList != NULL) {
      DEBUG ((DEBUG_INFO, "*** This Redfish Service was already found ***\n"));
      if (DiscoveredInstance->Information.Uuid != NULL) {
        DEBUG ((DEBUG_INFO, "Service UUID: %s.\n", DiscoveredInstance->Information.Uuid));
      } else {
        DEBUG ((DEBUG_INFO, "Service UUID: unknown.\n"));
      }
    }
  }

  if (Char16Uuid != NULL) {
    FreePool ((VOID *)Char16Uuid);
  }

  Status = EFI_SUCCESS;
  if (NewFound || InfoRefresh) {
    //
    // Build up EFI_REDFISH_DISCOVERED_LIST in token.
    //
    Instance->DiscoverToken->DiscoverList.NumberOfServiceFound = 1;
    Instance->DiscoverToken->DiscoverList.RedfishInstances     = DiscoveredInstance;
    DiscoveredInstance->Status                                 = EFI_SUCCESS;
    if (!InfoRefresh) {
      Status = CreateRestExInstance (Instance, Instance->DiscoverToken); // Create REST EX child.
      if (EFI_ERROR (Status)) {
        DEBUG ((DEBUG_ERROR, "%a:Can't create REST EX child instance.\n", __FUNCTION__));
        goto ON_EXIT;
      }

      Status = gBS->OpenProtocol (
                      // Configure local host information.
                      Instance->DiscoverToken->DiscoverList.RedfishInstances->Information.RedfishRestExHandle,
                      &gEfiRestExProtocolGuid,
                      (VOID **)&RestEx,
                      Instance->NetworkInterface->OpenDriverAgentHandle,
                      Instance->NetworkInterface->OpenDriverControllerHandle,
                      EFI_OPEN_PROTOCOL_BY_DRIVER
                      );
      if (EFI_ERROR (Status)) {
        DeleteRestEx = TRUE;
        goto ERROR_EXIT;
      }

      RestExOpened         = TRUE;
      RestExHttpConfigData = AllocateZeroPool (sizeof (EFI_REST_EX_HTTP_CONFIG_DATA));
      if (RestExHttpConfigData == NULL) {
        Status       = EFI_OUT_OF_RESOURCES;
        DeleteRestEx = TRUE;
        goto EXIT_FREE_CONFIG_DATA;
      }

      RestExHttpConfigData->SendReceiveTimeout                = 5000;
      RestExHttpConfigData->HttpConfigData.HttpVersion        = HttpVersion11;
      RestExHttpConfigData->HttpConfigData.LocalAddressIsIPv6 = CheckIsIpVersion6 (NetworkInterface);
      if (RestExHttpConfigData->HttpConfigData.LocalAddressIsIPv6) {
        RestExHttpConfigData->HttpConfigData.AccessPoint.IPv6Node = AllocateZeroPool (sizeof (EFI_HTTPv6_ACCESS_POINT));
        if (RestExHttpConfigData->HttpConfigData.AccessPoint.IPv6Node == NULL) {
          Status = EFI_OUT_OF_RESOURCES;
          goto EXIT_FREE_CONFIG_DATA;
        }
      } else {
        RestExHttpConfigData->HttpConfigData.AccessPoint.IPv4Node = AllocateZeroPool (sizeof (EFI_HTTPv4_ACCESS_POINT));
        if (RestExHttpConfigData->HttpConfigData.AccessPoint.IPv4Node == NULL) {
          Status = EFI_OUT_OF_RESOURCES;
          goto EXIT_FREE_CONFIG_DATA;
        }

        RestExHttpConfigData->HttpConfigData.AccessPoint.IPv4Node->UseDefaultAddress = TRUE;
      }

      Status = RestEx->Configure (
                         RestEx,
                         (EFI_REST_EX_CONFIG_DATA)(UINT8 *)RestExHttpConfigData
                         );
      if (EFI_ERROR (Status)) {
        DEBUG ((DEBUG_ERROR, "%a:REST EX configured..\n", __FUNCTION__));
        DeleteRestEx = TRUE;
        goto EXIT_FREE_ALL;
      }

      //
      // Signal client, close REST EX before signaling client.
      //
      if (RestExOpened) {
        gBS->CloseProtocol (
               Instance->DiscoverToken->DiscoverList.RedfishInstances->Information.RedfishRestExHandle,
               &gEfiRestExProtocolGuid,
               Instance->NetworkInterface->OpenDriverAgentHandle,
               Instance->NetworkInterface->OpenDriverControllerHandle
               );
        RestExOpened = FALSE;
      }
    }

    Status = gBS->SignalEvent (Instance->DiscoverToken->Event);
    if (!EFI_ERROR (Status)) {
      DEBUG ((DEBUG_ERROR, "%a:No event to signal!\n", __FUNCTION__));
    }
  }

EXIT_FREE_ALL:;
  if ((RestExHttpConfigData != NULL) && (RestExHttpConfigData->HttpConfigData.AccessPoint.IPv4Node != NULL)) {
    FreePool (RestExHttpConfigData->HttpConfigData.AccessPoint.IPv4Node);
  }

EXIT_FREE_CONFIG_DATA:;
  if (RestExHttpConfigData != NULL) {
    FreePool ((VOID *)RestExHttpConfigData);
  }

  if (RestExOpened) {
    gBS->CloseProtocol (
           Instance->DiscoverToken->DiscoverList.RedfishInstances->Information.RedfishRestExHandle,
           &gEfiRestExProtocolGuid,
           Instance->NetworkInterface->OpenDriverAgentHandle,
           Instance->NetworkInterface->OpenDriverControllerHandle
           );
  }

ERROR_EXIT:;
  if (DeleteRestEx && RestExOpened) {
    gBS->CloseProtocol (
           Instance->DiscoverToken->DiscoverList.RedfishInstances->Information.RedfishRestExHandle,
           &gEfiRestExProtocolGuid,
           Instance->NetworkInterface->OpenDriverAgentHandle,
           Instance->NetworkInterface->OpenDriverControllerHandle
           );
  }

ON_EXIT:;
  return Status;
}

/**
  This function gets the subnet information of this network interface instance.
  can discover Redfish service on it.

  @param[in]    Instance     EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL instance.
  @param[in]    ImageHandle  EFI Image handle request the network interface list.

  @retval EFI_SUCCESS

**/
EFI_STATUS
NetworkInterfaceGetSubnetInfo (
  IN EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL  *Instance,
  IN EFI_HANDLE                                       ImageHandle
  )
{
  EFI_STATUS                                       Status;
  UINT32                                           ProtocolType;
  UINT32                                           IPv6InfoIndex;
  EFI_IP6_ADDRESS_INFO                             *ThisSubnetAddrInfoIPv6;
  EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL  *NewNetworkInterface;

  if (Instance->GotSubnetInfo) {
    return EFI_SUCCESS;
  }

  ProtocolType = Instance->NetworkProtocolType;
  if ((gRequiredProtocol[ProtocolType].GetSubnetInfo != NULL) && (Instance->GotSubnetInfo == FALSE)) {
    Status = gRequiredProtocol[ProtocolType].GetSubnetInfo (
                                               ImageHandle,
                                               Instance
                                               );
    if (EFI_ERROR (Status)) {
      DEBUG ((DEBUG_ERROR, "%a:Faile to get Subnet infomation.\n", __FUNCTION__));
      return Status;
    } else {
      DEBUG ((DEBUG_INFO, "%a:MAC address: %s\n", __FUNCTION__, Instance->StrMacAddr));
      if (CheckIsIpVersion6 (Instance)) {
        if (Instance->SubnetAddrInfoIPv6Number == 0) {
          DEBUG ((DEBUG_ERROR, "%a: There is no Subnet infomation for IPv6 network interface.\n", __FUNCTION__));
          return EFI_NOT_FOUND;
        }

        ThisSubnetAddrInfoIPv6 = Instance->SubnetAddrInfoIPv6; // First IPv6 address information.
        IP6_COPY_ADDRESS (&Instance->SubnetAddr.v6, &ThisSubnetAddrInfoIPv6->Address);
        Instance->SubnetPrefixLength = ThisSubnetAddrInfoIPv6->PrefixLength;
        DEBUG ((
          DEBUG_INFO,
          "   IPv6 Subnet ID:%d, Prefix length: %d.\n",
          ThisSubnetAddrInfoIPv6->Address.Addr[7] + (UINT16)ThisSubnetAddrInfoIPv6->Address.Addr[6] * 256,
          ThisSubnetAddrInfoIPv6->PrefixLength
          )
          );
        //
        // If this is IPv6, then we may have to propagate network interface for IPv6 network scopes
        // according to the Ipv6 address information.
        //
        ThisSubnetAddrInfoIPv6++;
        for (IPv6InfoIndex = 0; IPv6InfoIndex < Instance->SubnetAddrInfoIPv6Number - 1; IPv6InfoIndex++) {
          //
          // Build up addtional EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL instances.
          //
          NewNetworkInterface = (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *)AllocateZeroPool (sizeof (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL));
          if (NewNetworkInterface != NULL) {
            CopyMem ((VOID *)NewNetworkInterface, (VOID *)Instance, sizeof (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL)); // Clone information of first instance.
            IP6_COPY_ADDRESS (&NewNetworkInterface->SubnetAddr.v6, &ThisSubnetAddrInfoIPv6->Address);
            NewNetworkInterface->SubnetPrefixLength = ThisSubnetAddrInfoIPv6->PrefixLength;
            NewNetworkInterface->GotSubnetInfo      = TRUE;
            InsertTailList (&mEfiRedfishDiscoverNetworkInterface, &NewNetworkInterface->Entry);
            ThisSubnetAddrInfoIPv6++;
            mNumNetworkInterface++;
            DEBUG ((
              DEBUG_INFO,
              "   IPv6 Subnet ID:%d, Prefix length: %d.\n",
              ThisSubnetAddrInfoIPv6->Address.Addr[7] + (UINT16)ThisSubnetAddrInfoIPv6->Address.Addr[6] * 256,
              ThisSubnetAddrInfoIPv6->PrefixLength
              )
              );
          } else {
            return EFI_OUT_OF_RESOURCES;
          }
        }
      } else {
        DEBUG ((
          DEBUG_INFO,
          "   IPv4 Subnet:%d.%d.%d.%d Subnet mask: %d.%d.%d.%d.\n",
          Instance->SubnetAddr.v4.Addr[0],
          Instance->SubnetAddr.v4.Addr[1],
          Instance->SubnetAddr.v4.Addr[2],
          Instance->SubnetAddr.v4.Addr[3],
          Instance->SubnetMask.v4.Addr[0],
          Instance->SubnetMask.v4.Addr[1],
          Instance->SubnetMask.v4.Addr[2],
          Instance->SubnetMask.v4.Addr[3]
          ));
      }
    }
  }

  Instance->GotSubnetInfo = TRUE; // Only try to get Subnet Info once.
  return EFI_SUCCESS;
}

/**
  This function gets the network interface list which Redfish discover protocol
  can discover Redfish service on it.

  @param[in]    This                  EFI_REDFISH_DISCOVER_PROTOCOL instance.
  @param[in]    ImageHandle           EFI Image handle request the network interface list,
  @param[out]   NumberOfNetworkIntfs  Number of network interfaces can do Redfish service discovery.
  @param[out]   NetworkIntfInstances  Network interface instances. It's an array of instance. The number of entries
                                      in array is indicated by NumberOfNetworkIntfs.
                                      Caller has to release the memory
                                      allocated by Redfish discover protocol.

  @retval EFI_SUCCESS        The information of network interface is returned in NumberOfNetworkIntfs and
                             NetworkIntfInstances.
  @retval Others             Fail to return the information of network interface.

**/
EFI_STATUS
EFIAPI
RedfishServiceGetNetworkInterface (
  IN EFI_REDFISH_DISCOVER_PROTOCOL            *This,
  IN EFI_HANDLE                               ImageHandle,
  OUT UINTN                                   *NumberOfNetworkIntfs,
  OUT EFI_REDFISH_DISCOVER_NETWORK_INTERFACE  **NetworkIntfInstances
  )
{
  EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL  *ThisNetworkInterfaceIntn;
  EFI_REDFISH_DISCOVER_NETWORK_INTERFACE           *ThisNetworkInterface;

  if ((NetworkIntfInstances == NULL) || (NumberOfNetworkIntfs == NULL) || (ImageHandle == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  *NumberOfNetworkIntfs = 0;
  *NetworkIntfInstances = NULL;

  if (IsListEmpty ((const LIST_ENTRY *)&mEfiRedfishDiscoverNetworkInterface)) {
    return EFI_NOT_FOUND;
  }

  ThisNetworkInterface = (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE *)AllocateZeroPool (sizeof (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE) * mNumNetworkInterface);
  if (ThisNetworkInterface == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  *NetworkIntfInstances    = ThisNetworkInterface;
  ThisNetworkInterfaceIntn = (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *)GetFirstNode (&mEfiRedfishDiscoverNetworkInterface);
  while (TRUE) {
    ThisNetworkInterface->IsIpv6 = FALSE;
    if (CheckIsIpVersion6 (ThisNetworkInterfaceIntn)) {
      ThisNetworkInterface->IsIpv6 = TRUE;
    }

    CopyMem ((VOID *)&ThisNetworkInterface->MacAddress, &ThisNetworkInterfaceIntn->MacAddress, ThisNetworkInterfaceIntn->HwAddressSize);
    NetworkInterfaceGetSubnetInfo (ThisNetworkInterfaceIntn, ImageHandle); // Get subnet info.
    if (!ThisNetworkInterface->IsIpv6) {
      IP4_COPY_ADDRESS (&ThisNetworkInterface->SubnetId.v4, &ThisNetworkInterfaceIntn->SubnetAddr.v4); // IPv4 subnet information.
    } else {
      IP6_COPY_ADDRESS (&ThisNetworkInterface->SubnetId.v6, &ThisNetworkInterfaceIntn->SubnetAddr.v6); // IPv6 subnet information in IPv6 address information.
    }

    ThisNetworkInterface->SubnetPrefixLength = ThisNetworkInterfaceIntn->SubnetPrefixLength;
    ThisNetworkInterface->VlanId             = ThisNetworkInterfaceIntn->VlanId;
    (*NumberOfNetworkIntfs)++;
    if (IsNodeAtEnd (&mEfiRedfishDiscoverNetworkInterface, &ThisNetworkInterfaceIntn->Entry)) {
      break;
    }

    ThisNetworkInterfaceIntn = (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *)GetNextNode (&mEfiRedfishDiscoverNetworkInterface, &ThisNetworkInterfaceIntn->Entry);
    ThisNetworkInterface++;
  }

  return EFI_SUCCESS;
}

/**
  This function acquires Redfish services by discovering static Redfish setting
  according to Redfish Host Interface or through SSDP. Returns a list of EFI
  handles in EFI_REDFISH_DISCOVERED_LIST. Each of EFI handle has cooresponding
  EFI REST EX instance installed on it. Each REST EX isntance is a child instance which
  created through EFI REST EX serivce protoocl for communicating with specific
  Redfish service.

  @param[in]    This                    EFI_REDFISH_DISCOVER_PROTOCOL instance.
  @param[in]    ImageHandle             EFI image owns these Redfish service instances.
  @param[in]    TargetNetworkInterface  Target network interface to do the discovery.
                                        NULL means discover Redfish service on all network interfaces on platform.
  @param[in]    Flags                   Redfish service discover flags.
  @param[in]    Token                   EFI_REDFISH_DISCOVERED_TOKEN instance.
                                        The memory of EFI_REDFISH_DISCOVERED_LIST and the strings in
                                        EFI_REDFISH_DISCOVERED_INFORMATION are all allocated by Acquire()
                                        and must be freed when caller invoke Release().

  @retval EFI_SUCCESS             REST EX instance of discovered Redfish services are returned.
  @retval EFI_INVALID_PARAMETERS  ImageHandle == NULL, Flags == 0, Token == NULL, Token->Timeout > 5,
                                  or Token->Event == NULL.
  @retval Others                  Fail acquire Redfish services.

**/
EFI_STATUS
EFIAPI
RedfishServiceAcquireService (
  IN EFI_REDFISH_DISCOVER_PROTOCOL           *This,
  IN EFI_HANDLE                              ImageHandle,
  IN EFI_REDFISH_DISCOVER_NETWORK_INTERFACE  *TargetNetworkInterface,
  IN EFI_REDFISH_DISCOVER_FLAG               Flags,
  IN EFI_REDFISH_DISCOVERED_TOKEN            *Token
  )
{
  EFI_REDFISH_DISCOVERED_INTERNAL_INSTANCE         *Instance;
  EFI_STATUS                                       Status1;
  EFI_STATUS                                       Status2;
  BOOLEAN                                          NewInstance;
  UINTN                                            NumNetworkInterfaces;
  UINTN                                            NetworkInterfacesIndex;
  EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL  *TargetNetworkInterfaceInternal;

  DEBUG ((DEBUG_INFO, "%a:Entry.\n", __FUNCTION__));

  //
  // Validate parameters.
  //
  if ((ImageHandle == NULL) || (Token == NULL) || ((Flags & ~EFI_REDFISH_DISCOVER_VALIDATION) == 0)) {
    DEBUG ((DEBUG_ERROR, "%a:Invalid parameters.\n", __FUNCTION__));
    return EFI_INVALID_PARAMETER;
  }

  //
  // Validate target network interface.
  //
  if (EFI_ERROR (ValidateTargetNetworkInterface (TargetNetworkInterface, Flags))) {
    return EFI_UNSUPPORTED;
  }

  if (TargetNetworkInterface != NULL) {
    TargetNetworkInterfaceInternal = GetTargetNetworkInterfaceInternal (TargetNetworkInterface);
    NumNetworkInterfaces           = 1;
  } else {
    TargetNetworkInterfaceInternal = (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *)GetFirstNode (&mEfiRedfishDiscoverNetworkInterface);
    NumNetworkInterfaces           = NumberOfNetworkInterface ();
    if (NumNetworkInterfaces == 0) {
      DEBUG ((DEBUG_ERROR, "%a:No network interface on platform.\n", __FUNCTION__));
      return EFI_UNSUPPORTED;
    }
  }

  for (NetworkInterfacesIndex = 0; NetworkInterfacesIndex < NumNetworkInterfaces; NetworkInterfacesIndex++) {
    Status1     = EFI_SUCCESS;
    Status2     = EFI_SUCCESS;
    NewInstance = FALSE;
    Instance    = GetInstanceByOwner (ImageHandle, TargetNetworkInterfaceInternal, Flags & ~EFI_REDFISH_DISCOVER_VALIDATION); // Check if we can re-use previous instance.
    if (Instance == NULL) {
      DEBUG ((DEBUG_INFO, "%a:Create new EFI_REDFISH_DISCOVERED_INTERNAL_INSTANCE.\n", __FUNCTION__));
      Instance = (EFI_REDFISH_DISCOVERED_INTERNAL_INSTANCE *)AllocateZeroPool (sizeof (EFI_REDFISH_DISCOVERED_INTERNAL_INSTANCE));
      if (Instance == NULL) {
        DEBUG ((DEBUG_ERROR, "%a:Memory allocation fail.\n", __FUNCTION__));
      }

      InitializeListHead (&Instance->Entry);
      Instance->Owner            = ImageHandle;
      Instance->DiscoverFlags    = Flags & ~EFI_REDFISH_DISCOVER_VALIDATION;
      Instance->NetworkInterface = TargetNetworkInterfaceInternal;
      //
      // Get subnet information in case subnet information is not set because
      // RedfishServiceGetNetworkInterfaces hasn't been called yet.
      //
      NetworkInterfaceGetSubnetInfo (TargetNetworkInterfaceInternal, ImageHandle);
      NewInstance = TRUE;
    }

    if (TargetNetworkInterfaceInternal->StrMacAddr != NULL) {
      DEBUG ((DEBUG_INFO, "%a:Acquire Redfish service on network interface MAC address:%s.\n", __FUNCTION__, TargetNetworkInterfaceInternal->StrMacAddr));
    } else {
      DEBUG ((DEBUG_INFO, "%a:WARNING: No MAC address on this network interface.\n", __FUNCTION__));
    }

    Instance->DiscoverToken = Token; // Always use the latest Token passed by caller.
    if ((Flags & EFI_REDFISH_DISCOVER_HOST_INTERFACE) != 0) {
      DEBUG ((DEBUG_INFO, "%a:Redfish HOST interface discovery.\n", __FUNCTION__));
      Instance->HostIntfValidation = FALSE;
      if ((Flags & EFI_REDFISH_DISCOVER_VALIDATION) != 0) {
        Instance->HostIntfValidation = TRUE;
      }

      Status1 = DiscoverRedfishHostInterface (Instance); // Discover Redfish service through Redfish Host Interface.
    }

    if ((Flags & EFI_REDFISH_DISCOVER_SSDP) != 0) {
      DEBUG ((DEBUG_ERROR, "%a:Redfish service discovery through SSDP is not supported\n", __FUNCTION__));
      return EFI_UNSUPPORTED;
    } else {
      if (EFI_ERROR (Status1) && EFI_ERROR (Status2)) {
        FreePool ((VOID *)Instance);
        DEBUG ((DEBUG_ERROR, "%a:Something wrong on Redfish service discovery Status1=%x, Status2=%x.\n", __FUNCTION__, Status1, Status2));
      } else {
        if (NewInstance) {
          InsertTailList (&mRedfishDiscoverList, &Instance->Entry);
        }
      }
    }

    if (TargetNetworkInterface == NULL) {
      //
      // Discover Redfish services on all of network interfaces.
      //
      TargetNetworkInterfaceInternal = (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *)GetNextNode (&mEfiRedfishDiscoverNetworkInterface, &TargetNetworkInterfaceInternal->Entry);
    }
  }

  return EFI_SUCCESS;
}

/**
  This function aborts Redfish service discovery on the given network interface.

  @param[in]    This                    EFI_REDFISH_DISCOVER_PROTOCOL instance.
  @param[in]    TargetNetworkInterface  Target network interface to do the discovery.

  @retval EFI_SUCCESS             REST EX instance of discovered Redfish services are returned.
  @retval Others                  Fail to abort Redfish service discovery.

**/
EFI_STATUS
EFIAPI
RedfishServiceAbortAcquire (
  IN EFI_REDFISH_DISCOVER_PROTOCOL           *This,
  IN EFI_REDFISH_DISCOVER_NETWORK_INTERFACE  *TargetNetworkInterface OPTIONAL
  )
{
  // This function is used to abort Redfish service discovery through SSDP
  // on the network interface. SSDP is optionally supprted by EFI_REDFISH_DISCOVER_PROTOCOL,
  // we dont have implementation for SSDP now.

  return EFI_UNSUPPORTED;
}

/**
  This function releases Redfish services found by RedfishServiceAcquire().

  @param[in]    This         EFI_REDFISH_DISCOVER_PROTOCOL instance.
  @param[in]    InstanceList The Redfish service to release.

  @retval EFI_SUCCESS        REST EX instances of discovered Redfish are released.
  @retval Others             Fail to remove the entry

**/
EFI_STATUS
EFIAPI
RedfishServiceReleaseService (
  IN EFI_REDFISH_DISCOVER_PROTOCOL  *This,
  IN EFI_REDFISH_DISCOVERED_LIST    *InstanceList
  )
{
  UINTN                                 NumService;
  BOOLEAN                               AnyFailRelease;
  EFI_REDFISH_DISCOVERED_INSTANCE       *ThisRedfishInstance;
  EFI_REDFISH_DISCOVERED_INTERNAL_LIST  *DiscoveredRedfishInstance;

  if (IsListEmpty (&mRedfishInstanceList)) {
    DEBUG ((DEBUG_ERROR, "%a:No any discovered Redfish service.\n", __FUNCTION__));
    return EFI_NOT_FOUND;
  }

  AnyFailRelease      = FALSE;
  ThisRedfishInstance = InstanceList->RedfishInstances;
  for (NumService = 0; NumService < InstanceList->NumberOfServiceFound; NumService++) {
    DiscoveredRedfishInstance = (EFI_REDFISH_DISCOVERED_INTERNAL_LIST *)GetFirstNode (&mRedfishInstanceList);
    do {
      if (DiscoveredRedfishInstance->Instance == ThisRedfishInstance) {
        RemoveEntryList (&DiscoveredRedfishInstance->NextInstance);
        if (ThisRedfishInstance->Information.Location != NULL) {
          FreePool (ThisRedfishInstance->Information.Location);
        }

        if (ThisRedfishInstance->Information.Uuid != NULL) {
          FreePool (ThisRedfishInstance->Information.Uuid);
        }

        if (ThisRedfishInstance->Information.Os != NULL) {
          FreePool (ThisRedfishInstance->Information.Os);
        }

        if (ThisRedfishInstance->Information.OsVersion != NULL) {
          FreePool (ThisRedfishInstance->Information.OsVersion);
        }

        if (ThisRedfishInstance->Information.Product != NULL) {
          FreePool (ThisRedfishInstance->Information.Product);
        }

        if (ThisRedfishInstance->Information.ProductVer != NULL) {
          FreePool (ThisRedfishInstance->Information.ProductVer);
        }

        FreePool ((VOID *)ThisRedfishInstance);
        goto ReleaseNext;
      }

      if (IsNodeAtEnd (&mRedfishInstanceList, &DiscoveredRedfishInstance->NextInstance)) {
        break;
      }

      DiscoveredRedfishInstance = (EFI_REDFISH_DISCOVERED_INTERNAL_LIST *)GetNextNode (&mRedfishInstanceList, &DiscoveredRedfishInstance->NextInstance);
    } while (TRUE);

    AnyFailRelease = TRUE;
ReleaseNext:;
    //
    // Release next discovered Redfish Service.
    //
    ThisRedfishInstance = (EFI_REDFISH_DISCOVERED_INSTANCE *)((UINT8 *)ThisRedfishInstance + sizeof (EFI_REDFISH_DISCOVERED_INSTANCE));
  }

  if (AnyFailRelease) {
    return EFI_NOT_FOUND;
  } else {
    return EFI_SUCCESS;
  }
}

EFI_REDFISH_DISCOVER_PROTOCOL  mRedfishDiscover = {
  RedfishServiceGetNetworkInterface,
  RedfishServiceAcquireService,
  RedfishServiceAbortAcquire,
  RedfishServiceReleaseService
};

/**
  This function create an EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL for the
  given network interface.


  @param[in]  ControllerHandle    MAC address of this network interface.
  @param[in]  NetworkProtocolType Network protocol type.
  @param[out] IsNewInstance       BOOLEAN means new instance or not.
  @param[out] NetworkInterface    Pointer to to EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL.

  @retval EFI_STATUS
**/
EFI_STATUS
CreateRedfishDiscoverNetworkInterface (
  IN EFI_HANDLE                                        ControllerHandle,
  IN UINT32                                            NetworkProtocolType,
  OUT BOOLEAN                                          *IsNewInstance,
  OUT EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL  **NetworkInterface
  )
{
  EFI_MAC_ADDRESS                                  MacAddress;
  UINTN                                            HwAddressSize;
  EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL  *ThisNetworkInterface;
  EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL  *NewNetworkInterface;

  NetLibGetMacAddress (ControllerHandle, &MacAddress, &HwAddressSize);
  NewNetworkInterface = NULL;
  *IsNewInstance      = TRUE;
  if (!IsListEmpty ((const LIST_ENTRY *)&mEfiRedfishDiscoverNetworkInterface)) {
    //
    // Check if this instance already exist.
    //
    ThisNetworkInterface = (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *)GetFirstNode (&mEfiRedfishDiscoverNetworkInterface);
    if (ThisNetworkInterface != NULL) {
      while (TRUE) {
        if ((CompareMem ((CONST VOID *)&ThisNetworkInterface->MacAddress.Addr, (CONST VOID *)&MacAddress.Addr, HwAddressSize) == 0) &&
            (ThisNetworkInterface->NetworkProtocolType == NetworkProtocolType))
        {
          NewNetworkInterface = ThisNetworkInterface;
          *IsNewInstance      = FALSE;
          break;
        }

        if (IsNodeAtEnd (&mEfiRedfishDiscoverNetworkInterface, &ThisNetworkInterface->Entry)) {
          NewNetworkInterface = NULL;
          break;
        }

        ThisNetworkInterface = (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *)GetNextNode (&mEfiRedfishDiscoverNetworkInterface, &ThisNetworkInterface->Entry);
      }
    }
  }

  if (NewNetworkInterface == NULL) {
    //
    // Create a new instance.
    //
    NewNetworkInterface = (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *)AllocateZeroPool (sizeof (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL));
    if (NewNetworkInterface == NULL) {
      return EFI_OUT_OF_RESOURCES;
    }

    NewNetworkInterface->HwAddressSize = HwAddressSize;
    CopyMem (&NewNetworkInterface->MacAddress.Addr, &MacAddress.Addr, NewNetworkInterface->HwAddressSize);
    NetLibGetMacString (ControllerHandle, NULL, &NewNetworkInterface->StrMacAddr);
    NewNetworkInterface->VlanId = NetLibGetVlanId (ControllerHandle);
  }

  *NetworkInterface = NewNetworkInterface;
  return EFI_SUCCESS;
}

/**
  This function destory network interface


  @param[in]  ThisNetworkInterface EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL instance.

  @retval EFI_STATUS
**/
EFI_STATUS
DestroyRedfishNetwrokInterface (
  IN EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL  *ThisNetworkInterface
  )
{
  EFI_STATUS  Status;

  Status = gBS->UninstallProtocolInterface (
                  ThisNetworkInterface->OpenDriverControllerHandle,
                  gRequiredProtocol[ThisNetworkInterface->NetworkProtocolType].DiscoveredProtocolGuid,
                  &ThisNetworkInterface->NetworkInterfaceProtocolInfo.ProtocolDiscoverId
                  );
  RemoveEntryList (&ThisNetworkInterface->Entry);
  mNumNetworkInterface--;
  FreePool (ThisNetworkInterface);
  return Status;
}

/**
  Tests to see if the required protocols are provided on the given
  controller handle.

  @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.
  @retval EFI_SUCCESS              One of required protocol is found.
  @retval EFI_UNSUPPORTED          None of required protocol is found.
**/
EFI_STATUS
TestForRequiredProtocols (
  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
  IN EFI_HANDLE                   ControllerHandle
  )
{
  UINT32      Id;
  UINTN       Index;
  EFI_STATUS  Status;

  for (Index = 0; Index < (sizeof (gRequiredProtocol) / sizeof (REDFISH_DISCOVER_REQUIRED_PROTOCOL)); Index++) {
    Status = gBS->OpenProtocol (
                    ControllerHandle,
                    gRequiredProtocol[Index].RequiredServiceBindingProtocolGuid,
                    NULL,
                    This->DriverBindingHandle,
                    ControllerHandle,
                    EFI_OPEN_PROTOCOL_TEST_PROTOCOL
                    );
    if (!EFI_ERROR (Status)) {
      Status = gBS->OpenProtocol (
                      ControllerHandle,
                      gRequiredProtocol[Index].DiscoveredProtocolGuid,
                      (VOID **)&Id,
                      This->DriverBindingHandle,
                      ControllerHandle,
                      EFI_OPEN_PROTOCOL_GET_PROTOCOL
                      );
      if (EFI_ERROR (Status)) {
        DEBUG ((DEBUG_ERROR, "%a: %s is found on this controller handle.\n", __FUNCTION__, gRequiredProtocol[Index].ProtocolName));
        return EFI_SUCCESS;
      }
    }
  }

  return EFI_UNSUPPORTED;
}

/**
  Build up network interface and create corresponding service through the given
  controller handle.

  @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.
  @retval EFI_SUCCESS              One of required protocol is found.
  @retval EFI_UNSUPPORTED          None of required protocol is found.
  @retval EFI_UNSUPPORTED          Failed to build up network interface.
**/
EFI_STATUS
BuildupNetworkInterface (
  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
  IN EFI_HANDLE                   ControllerHandle
  )
{
  UINT32                                           Id;
  UINT32                                           Index;
  EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL  *NetworkInterface;
  BOOLEAN                                          IsNew;
  EFI_STATUS                                       Status;
  VOID                                             *TempInterface;
  VOID                                             **Interface;
  UINT32                                           *ProtocolDiscoverIdPtr;
  EFI_HANDLE                                       OpenDriverAgentHandle;
  EFI_HANDLE                                       OpenDriverControllerHandle;
  EFI_HANDLE                                       *HandleOfProtocolInterfacePtr;
  EFI_REDFISH_DISCOVER_REST_EX_INSTANCE_INTERNAL   *RestExInstance;
  EFI_TPL                                          OldTpl;
  BOOLEAN                                          NewNetworkInterfaceInstalled;

  NewNetworkInterfaceInstalled = FALSE;
  Index                        = 0;
  do {
    Status = gBS->OpenProtocol (
                    // Already in list?
                    ControllerHandle,
                    gRequiredProtocol[Index].DiscoveredProtocolGuid,
                    (VOID **)&Id,
                    This->DriverBindingHandle,
                    ControllerHandle,
                    EFI_OPEN_PROTOCOL_GET_PROTOCOL
                    );
    if (!EFI_ERROR (Status)) {
      Index++;
      if (Index == (sizeof (gRequiredProtocol) / sizeof (REDFISH_DISCOVER_REQUIRED_PROTOCOL))) {
        break;
      }

      continue;
    }

    Status = gBS->OpenProtocol (
                    ControllerHandle,
                    gRequiredProtocol[Index].RequiredServiceBindingProtocolGuid,
                    &TempInterface,
                    This->DriverBindingHandle,
                    ControllerHandle,
                    EFI_OPEN_PROTOCOL_GET_PROTOCOL
                    );
    if (EFI_ERROR (Status)) {
      Index++;
      if (Index == (sizeof (gRequiredProtocol) / sizeof (REDFISH_DISCOVER_REQUIRED_PROTOCOL))) {
        break;
      }

      continue;
    }

    if (gRequiredProtocol[Index].ProtocolType != ProtocolTypeRestEx) {
      OldTpl = gBS->RaiseTPL (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_TPL);
      Status = CreateRedfishDiscoverNetworkInterface (ControllerHandle, gRequiredProtocol[Index].ProtocolType, &IsNew, &NetworkInterface);
      if (EFI_ERROR (Status)) {
        gBS->RestoreTPL (OldTpl);
        return Status;
      }

      NetworkInterface->NetworkProtocolType                       = gRequiredProtocol[Index].ProtocolType;
      NetworkInterface->OpenDriverAgentHandle                     = This->DriverBindingHandle;
      NetworkInterface->OpenDriverControllerHandle                = ControllerHandle;
      NetworkInterface->NetworkInterfaceProtocolInfo.ProtocolGuid = \
        *gRequiredProtocol[Index].RequiredProtocolGuid;
      NetworkInterface->NetworkInterfaceProtocolInfo.ProtocolServiceGuid = \
        *gRequiredProtocol[Index].RequiredServiceBindingProtocolGuid;
      ProtocolDiscoverIdPtr        = &NetworkInterface->NetworkInterfaceProtocolInfo.ProtocolDiscoverId;
      OpenDriverAgentHandle        = NetworkInterface->OpenDriverAgentHandle;
      OpenDriverControllerHandle   = NetworkInterface->OpenDriverControllerHandle;
      HandleOfProtocolInterfacePtr = &NetworkInterface->NetworkInterfaceProtocolInfo.ProtocolControllerHandle;
      Interface                    = &NetworkInterface->NetworkInterfaceProtocolInfo.NetworkProtocolInterface;
      NewNetworkInterfaceInstalled = TRUE;
      if (IsNew) {
        InsertTailList (&mEfiRedfishDiscoverNetworkInterface, &NetworkInterface->Entry);
        mNumNetworkInterface++;
      }

      gBS->RestoreTPL (OldTpl);
    } else {
      // Record REST_EX instance. REST_EX is created when clinet asks for Redfish service discovery.
      // Redfish Service Discover protocol will match REST EX to the corresponding EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL
      // when discovery.

      RestExInstance = (EFI_REDFISH_DISCOVER_REST_EX_INSTANCE_INTERNAL *)AllocateZeroPool (sizeof (EFI_REDFISH_DISCOVER_REST_EX_INSTANCE_INTERNAL));
      if (RestExInstance == NULL) {
        return EFI_OUT_OF_RESOURCES;
      }

      RestExInstance->OpenDriverAgentHandle      = This->DriverBindingHandle;
      RestExInstance->OpenDriverControllerHandle = ControllerHandle;
      RestExInstance->RestExControllerHandle     = ControllerHandle;
      InitializeListHead (&RestExInstance->Entry);
      InsertTailList (&mEfiRedfishDiscoverRestExInstance, &RestExInstance->Entry);
      mNumRestExInstance++;
      ProtocolDiscoverIdPtr        = &RestExInstance->RestExId;
      OpenDriverAgentHandle        = RestExInstance->OpenDriverAgentHandle;
      OpenDriverControllerHandle   = RestExInstance->OpenDriverControllerHandle;
      HandleOfProtocolInterfacePtr = &RestExInstance->RestExChildHandle;
      Interface                    = (VOID **)&RestExInstance->RestExProtocolInterface;
    }

    Status = gBS->InstallProtocolInterface (
                    &ControllerHandle,
                    gRequiredProtocol[Index].DiscoveredProtocolGuid,
                    EFI_NATIVE_INTERFACE,
                    ProtocolDiscoverIdPtr
                    );
    if (EFI_ERROR (Status)) {
      Index++;
      if (Index == (sizeof (gRequiredProtocol) / sizeof (REDFISH_DISCOVER_REQUIRED_PROTOCOL))) {
        break;
      }

      continue;
    }

    //
    // Create service binding child and open it BY_DRIVER.
    //
    Status = NetLibCreateServiceChild (
               ControllerHandle,
               This->ImageHandle,
               gRequiredProtocol[Index].RequiredServiceBindingProtocolGuid,
               HandleOfProtocolInterfacePtr
               );
    if (!EFI_ERROR (Status)) {
      Status = gBS->OpenProtocol (
                      *HandleOfProtocolInterfacePtr,
                      gRequiredProtocol[Index].RequiredProtocolGuid,
                      Interface,
                      OpenDriverAgentHandle,
                      OpenDriverControllerHandle,
                      EFI_OPEN_PROTOCOL_BY_DRIVER
                      );
      if (!EFI_ERROR (Status)) {
        if ((gRequiredProtocol[Index].ProtocolType == ProtocolTypeRestEx)) {
          // Install Redfish Discover Protocol when EFI REST EX protcol is discovered.
          // This ensures EFI REST EX is ready while the consumer of EFI_REDFISH_DISCOVER_PROTOCOL
          // acquires Redfish serivce over network interface.

          if (!NewNetworkInterfaceInstalled) {
            NetworkInterface = GetTargetNetworkInterfaceInternalByController (ControllerHandle);
            if (NetworkInterface == NULL) {
              DEBUG ((DEBUG_ERROR, "%a: Can't find network interface by ControllerHandle\n", __FUNCTION__));
              return Status;
            }
          }

          NewNetworkInterfaceInstalled                       = FALSE;
          NetworkInterface->EfiRedfishDiscoverProtocolHandle = NULL;
          Status                                             = gBS->InstallProtocolInterface (
                                                                      &NetworkInterface->EfiRedfishDiscoverProtocolHandle,
                                                                      &gEfiRedfishDiscoverProtocolGuid,
                                                                      EFI_NATIVE_INTERFACE,
                                                                      (VOID *)&mRedfishDiscover
                                                                      );
          if (EFI_ERROR (Status)) {
            DEBUG ((DEBUG_ERROR, "%a: Fail to install EFI_REDFISH_DISCOVER_PROTOCOL\n", __FUNCTION__));
          }
        }
      }

      return Status;
    } else {
      Index++;
      if (Index == (sizeof (gRequiredProtocol) / sizeof (REDFISH_DISCOVER_REQUIRED_PROTOCOL))) {
        break;
      }

      continue;
    }
  } while (Index < (sizeof (gRequiredProtocol) / sizeof (REDFISH_DISCOVER_REQUIRED_PROTOCOL)));

  return EFI_UNSUPPORTED;
}

/**
  Close the protocol opened for Redfish discovery. This function also destories
  the network services.

  @param[in]  ThisBindingProtocol     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]  ThisRequiredProtocol    Pointer to the instance of REDFISH_DISCOVER_REQUIRED_PROTOCOL.
  @param[in]  DriverAgentHandle      Driver agent handle which used to open protocol earlier.
  @param[in]  DriverControllerHandle Driver controller handle which used to open protocol earlier.

  @retval EFI_SUCCESS                Prorocol is closed successfully.
  @retval Others                     Prorocol is closed unsuccessfully.

**/
EFI_STATUS
CloseProtocolService (
  IN EFI_DRIVER_BINDING_PROTOCOL         *ThisBindingProtocol,
  IN EFI_HANDLE                          ControllerHandle,
  IN REDFISH_DISCOVER_REQUIRED_PROTOCOL  *ThisRequiredProtocol,
  IN EFI_HANDLE                          DriverAgentHandle,
  IN EFI_HANDLE                          DriverControllerHandle
  )
{
  EFI_STATUS  Status;

  Status = gBS->CloseProtocol (
                  ControllerHandle,
                  ThisRequiredProtocol->RequiredProtocolGuid,
                  DriverAgentHandle,
                  DriverControllerHandle
                  );
  if (!EFI_ERROR (Status)) {
    NetLibDestroyServiceChild (
      ControllerHandle,
      ThisBindingProtocol->ImageHandle,
      ThisRequiredProtocol->RequiredServiceBindingProtocolGuid,
      ControllerHandle
      );
  }

  return Status;
}

/**
  Stop the services on network interface.

  @param[in]  ThisBindingProtocol  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.
  @retval EFI_SUCCESS              One of required protocol is found.
  @retval Others                   Faile to stop the services on network interface.
**/
EFI_STATUS
StopServiceOnNetworkInterface (
  IN EFI_DRIVER_BINDING_PROTOCOL  *ThisBindingProtocol,
  IN EFI_HANDLE                   ControllerHandle
  )
{
  UINT32                                           Index;
  EFI_STATUS                                       Status;
  VOID                                             *Interface;
  EFI_TPL                                          OldTpl;
  EFI_HANDLE                                       DiscoverProtocolHandle;
  EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL  *ThisNetworkInterface;
  EFI_REDFISH_DISCOVER_REST_EX_INSTANCE_INTERNAL   *RestExInstance;

  for (Index = 0; Index < (sizeof (gRequiredProtocol) / sizeof (REDFISH_DISCOVER_REQUIRED_PROTOCOL)); Index++) {
    Status = gBS->HandleProtocol (
                    ControllerHandle,
                    gRequiredProtocol[Index].RequiredProtocolGuid,
                    (VOID **)&Interface
                    );
    if (!EFI_ERROR (Status)) {
      if (gRequiredProtocol[Index].ProtocolType != ProtocolTypeRestEx) {
        if (IsListEmpty (&mEfiRedfishDiscoverNetworkInterface)) {
          return EFI_NOT_FOUND;
        }

        OldTpl               = gBS->RaiseTPL (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_TPL);
        ThisNetworkInterface = (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *)GetFirstNode (&mEfiRedfishDiscoverNetworkInterface);
        while (TRUE) {
          if (ThisNetworkInterface->NetworkInterfaceProtocolInfo.ProtocolControllerHandle == ControllerHandle) {
            DiscoverProtocolHandle = ThisNetworkInterface->EfiRedfishDiscoverProtocolHandle;
            //
            // Close protocol and destroy service.
            //
            Status = CloseProtocolService (
                       ThisBindingProtocol,
                       ControllerHandle,
                       &gRequiredProtocol[Index],
                       ThisNetworkInterface->OpenDriverAgentHandle,
                       ThisNetworkInterface->OpenDriverControllerHandle
                       );
            if (!EFI_ERROR (Status)) {
              Status = DestroyRedfishNetwrokInterface (ThisNetworkInterface);
            }

            gBS->RestoreTPL (OldTpl);

            //
            // Disconnect EFI Redfish discover driver controller to notify the
            // clinet which uses .EFI Redfish discover protocol.
            //
            if (DiscoverProtocolHandle != NULL) {
              gBS->DisconnectController (DiscoverProtocolHandle, NULL, NULL);
              Status = gBS->UninstallProtocolInterface (
                              DiscoverProtocolHandle,
                              &gEfiRedfishDiscoverProtocolGuid,
                              (VOID *)&mRedfishDiscover
                              );
            }

            return Status;
          }

          if (IsNodeAtEnd (&mEfiRedfishDiscoverNetworkInterface, &ThisNetworkInterface->Entry)) {
            break;
          }

          ThisNetworkInterface = (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *)GetNextNode (&mEfiRedfishDiscoverNetworkInterface, &ThisNetworkInterface->Entry);
        }

        gBS->RestoreTPL (OldTpl);
      } else {
        if (IsListEmpty (&mEfiRedfishDiscoverRestExInstance)) {
          return EFI_NOT_FOUND;
        }

        OldTpl         = gBS->RaiseTPL (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_TPL);
        RestExInstance = (EFI_REDFISH_DISCOVER_REST_EX_INSTANCE_INTERNAL *)GetFirstNode (&mEfiRedfishDiscoverRestExInstance);
        while (TRUE) {
          if (RestExInstance->RestExChildHandle == ControllerHandle) {
            Status = CloseProtocolService (
                       // Close REST_EX protocol.
                       ThisBindingProtocol,
                       ControllerHandle,
                       &gRequiredProtocol[Index],
                       RestExInstance->OpenDriverAgentHandle,
                       RestExInstance->OpenDriverControllerHandle
                       );
            RemoveEntryList (&RestExInstance->Entry);
            FreePool ((VOID *)RestExInstance);
            mNumRestExInstance--;
            gBS->RestoreTPL (OldTpl);
            return Status;
          }

          if (IsNodeAtEnd (&mEfiRedfishDiscoverRestExInstance, &RestExInstance->Entry)) {
            break;
          }

          RestExInstance = (EFI_REDFISH_DISCOVER_REST_EX_INSTANCE_INTERNAL *)GetNextNode (&mEfiRedfishDiscoverRestExInstance, &RestExInstance->Entry);
        }

        gBS->RestoreTPL (OldTpl);
      }
    }
  }

  return EFI_NOT_FOUND;
}

/**
  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
RedfishDiscoverDriverBindingSupported (
  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
  IN EFI_HANDLE                   ControllerHandle,
  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath OPTIONAL
  )
{
  return TestForRequiredProtocols (This, ControllerHandle);
}

/**
  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
RedfishDiscoverDriverBindingStart (
  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
  IN EFI_HANDLE                   ControllerHandle,
  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath OPTIONAL
  )
{
  return BuildupNetworkInterface (This, ControllerHandle);
}

/**
  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
RedfishDiscoverDriverBindingStop (
  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
  IN EFI_HANDLE                   ControllerHandle,
  IN UINTN                        NumberOfChildren,
  IN EFI_HANDLE                   *ChildHandleBuffer OPTIONAL
  )
{
  return StopServiceOnNetworkInterface (This, ControllerHandle);
}

EFI_DRIVER_BINDING_PROTOCOL  gRedfishDiscoverDriverBinding = {
  RedfishDiscoverDriverBindingSupported,
  RedfishDiscoverDriverBindingStart,
  RedfishDiscoverDriverBindingStop,
  REDFISH_DISCOVER_VERSION,
  NULL,
  NULL
};

/**
  This is the declaration of an EFI image entry point.

  @param  ImageHandle           The firmware allocated handle for the UEFI image.
  @param  SystemTable           A pointer to the EFI System Table.

  @retval EFI_SUCCESS           The operation completed successfully.
  @retval Others                An unexpected error occurred.
**/
EFI_STATUS
EFIAPI
RedfishDiscoverEntryPoint (
  IN EFI_HANDLE        ImageHandle,
  IN EFI_SYSTEM_TABLE  *SystemTable
  )
{
  EFI_STATUS  Status;

  Status = EFI_SUCCESS;
  InitializeListHead (&mRedfishDiscoverList);
  InitializeListHead (&mRedfishInstanceList);
  InitializeListHead (&mEfiRedfishDiscoverNetworkInterface);
  InitializeListHead (&mEfiRedfishDiscoverRestExInstance);
  //
  // Install binding protoocl to obtain UDP and REST EX protocol.
  //
  Status = EfiLibInstallDriverBindingComponentName2 (
             ImageHandle,
             SystemTable,
             &gRedfishDiscoverDriverBinding,
             ImageHandle,
             &gRedfishDiscoverComponentName,
             &gRedfishDiscoverComponentName2
             );
  return Status;
}

/**
  This is the unload handle for Redfish discover module.

  Disconnect the driver specified by ImageHandle from all the devices in the handle database.
  Uninstall all the protocols installed in the driver entry point.

  @param[in] ImageHandle           The drivers' driver image.

  @retval    EFI_SUCCESS           The image is unloaded.
  @retval    Others                Failed to unload the image.

**/
EFI_STATUS
EFIAPI
RedfishDiscoverUnload (
  IN EFI_HANDLE  ImageHandle
  )
{
  EFI_STATUS                                       Status;
  EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL  *ThisNetworkInterface;

  Status = EFI_SUCCESS;
  // Destroy all network interfaces found by EFI Redfish Discover driver and
  // stop services created for Redfish Discover.

  while (!IsListEmpty (&mEfiRedfishDiscoverNetworkInterface)) {
    ThisNetworkInterface = (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *)GetFirstNode (&mEfiRedfishDiscoverNetworkInterface);
    StopServiceOnNetworkInterface (&gRedfishDiscoverDriverBinding, ThisNetworkInterface->NetworkInterfaceProtocolInfo.ProtocolControllerHandle);
  }

  return Status;
}
