/** @file

  The implementation of EFI Redfish Discover Protocol.

  (C) Copyright 2021 Hewlett Packard Enterprise Development LP<BR>
  Copyright (c) 2022, AMD Incorporated. All rights reserved.
  Copyright (c) 2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
  Copyright (c) 2023, Ampere Computing LLC. All rights reserved.<BR>

  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->NetworkInterface->OpenDriverControllerHandle,
             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", __func__));
    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", __func__));
    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", __func__));
    return Status;
  }

  if (IpModedata.AddressCount == 0) {
    DEBUG ((DEBUG_MANAGEABILITY, "%a: No IPv6 address configured.\n", __func__));
    Instance->SubnetAddrInfoIPv6Number = 0;
    return EFI_SUCCESS;
  }

  if (Instance->SubnetAddrInfoIPv6 != NULL) {
    FreePool (Instance->SubnetAddrInfoIPv6);
    Instance->SubnetAddrInfoIPv6 = NULL;
  }

  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", __func__));
    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
  network 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 through 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                          MacCompareStatus;
  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)) {
    //
    // Check if we can reach out Redfish service using this network interface.
    // Check with MAC address using Device Descriptor 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) {
      MacCompareStatus = CompareMem (&Instance->NetworkInterface->MacAddress, &DeviceDescriptor->DeviceDescriptor.PciPcieDeviceV2.MacAddress, 6);
    } else if (DeviceDescriptor->DeviceType == REDFISH_HOST_INTERFACE_DEVICE_TYPE_USB_V2) {
      MacCompareStatus = CompareMem (&Instance->NetworkInterface->MacAddress, &DeviceDescriptor->DeviceDescriptor.UsbDeviceV2.MacAddress, 6);
    } else {
      return EFI_UNSUPPORTED;
    }

    if (MacCompareStatus != 0) {
      return EFI_UNSUPPORTED;
    }

    Instance->HostAddrFormat = Data->HostIpAddressFormat;
    if (Data->HostIpAddressFormat == REDFISH_HOST_INTERFACE_HOST_IP_ADDRESS_FORMAT_IP4) {
      IP4_COPY_ADDRESS ((VOID *)&Instance->HostIpAddress.v4, (VOID *)Data->HostIpAddress);
      IP4_COPY_ADDRESS ((VOID *)&Instance->HostSubnetMask.v4, (VOID *)Data->HostIpMask);

      if (EFI_IP4_EQUAL (&Instance->HostIpAddress.v4, &mZeroIp4Addr)) {
        DEBUG ((DEBUG_ERROR, "%a: invalid host IP address: zero address\n", __func__));
        //
        // Invalid IP address detected. Change address format to Unknown and use system default address.
        //
        Instance->HostAddrFormat = REDFISH_HOST_INTERFACE_HOST_IP_ADDRESS_FORMAT_UNKNOWN;
      }

      if (!IP4_IS_VALID_NETMASK (EFI_IP4 (Instance->HostSubnetMask.v4))) {
        DEBUG ((DEBUG_ERROR, "%a: invalid subnet mask address\n", __func__));
        //
        // Invalid subnet mast address detected. Change address format to Unknown and use system default address.
        //
        Instance->HostAddrFormat = REDFISH_HOST_INTERFACE_HOST_IP_ADDRESS_FORMAT_UNKNOWN;
      }
    } else if (Data->HostIpAddressFormat == REDFISH_HOST_INTERFACE_HOST_IP_ADDRESS_FORMAT_IP6) {
      IP6_COPY_ADDRESS ((VOID *)&Instance->HostIpAddress.v6, (VOID *)Data->HostIpAddress);
    }

    if (Data->RedfishServiceIpAddressFormat == REDFISH_HOST_INTERFACE_HOST_IP_ADDRESS_FORMAT_IP4) {
      IP4_COPY_ADDRESS ((VOID *)&Instance->TargetIpAddress.v4, (VOID *)Data->RedfishServiceIpAddress);

      if (EFI_IP4_EQUAL (&Instance->TargetIpAddress.v4, &mZeroIp4Addr)) {
        DEBUG ((DEBUG_ERROR, "%a: invalid service IP address: zero address\n", __func__));
      }
    } 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", __func__));
      Status = EFI_UNSUPPORTED;
    } else {
      //
      // Add this instance to list without detail 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 version 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_MANAGEABILITY, "%a:Add this instance to Redfish instance list.\n", __func__));

  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 address.
        //
        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_MANAGEABILITY, "*** 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_MANAGEABILITY, "*** Redfish Service Information ***\n"));

    DiscoveredInstance->Information.UseHttps = UseHttps;
    if (RedfishVersion != NULL) {
      DiscoveredInstance->Information.RedfishVersion = *RedfishVersion;
      DEBUG ((DEBUG_MANAGEABILITY, "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_MANAGEABILITY, "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_MANAGEABILITY, "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_MANAGEABILITY, "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_MANAGEABILITY, "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_MANAGEABILITY, "*** This Redfish Service was already found ***\n"));
      if (DiscoveredInstance->Information.Uuid != NULL) {
        DEBUG ((DEBUG_MANAGEABILITY, "Service UUID: %s.\n", DiscoveredInstance->Information.Uuid));
      } else {
        DEBUG ((DEBUG_MANAGEABILITY, "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", __func__));
        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;
        }

        if (Instance->HostAddrFormat == REDFISH_HOST_INTERFACE_HOST_IP_ADDRESS_FORMAT_IP6) {
          IP6_COPY_ADDRESS (&RestExHttpConfigData->HttpConfigData.AccessPoint.IPv6Node->LocalAddress, &Instance->HostIpAddress.v6);
        }
      } 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;
        }

        if (Instance->HostAddrFormat == REDFISH_HOST_INTERFACE_HOST_IP_ADDRESS_FORMAT_IP4) {
          RestExHttpConfigData->HttpConfigData.AccessPoint.IPv4Node->UseDefaultAddress = FALSE;
          IP4_COPY_ADDRESS (&RestExHttpConfigData->HttpConfigData.AccessPoint.IPv4Node->LocalAddress, &Instance->HostIpAddress.v4);
          IP4_COPY_ADDRESS (&RestExHttpConfigData->HttpConfigData.AccessPoint.IPv4Node->LocalSubnet, &Instance->HostSubnetMask.v4);
        } else {
          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", __func__));
        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", __func__));
    }
  }

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:Failed to get Subnet infomation.\n", __func__));
      return Status;
    } else {
      DEBUG ((DEBUG_MANAGEABILITY, "%a:MAC address: %s\n", __func__, Instance->StrMacAddr));
      if (CheckIsIpVersion6 (Instance)) {
        if (Instance->SubnetAddrInfoIPv6Number == 0) {
          DEBUG ((DEBUG_ERROR, "%a: There is no Subnet infomation for IPv6 network interface.\n", __func__));
          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_MANAGEABILITY,
          "   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 additional 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_MANAGEABILITY,
              "   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_MANAGEABILITY,
          "   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;
  EFI_REDFISH_DISCOVER_REST_EX_INSTANCE_INTERNAL   *RestExInstance;

  if ((This == NULL) || (NetworkIntfInstances == NULL) || (NumberOfNetworkIntfs == NULL) ||
      (ImageHandle == NULL))
  {
    return EFI_INVALID_PARAMETER;
  }

  *NumberOfNetworkIntfs = 0;
  *NetworkIntfInstances = NULL;

  if (IsListEmpty ((const LIST_ENTRY *)&mEfiRedfishDiscoverNetworkInterface)) {
    return EFI_NOT_FOUND;
  }

  RestExInstance = EFI_REDFISH_DISOVER_DATA_FROM_DISCOVER_PROTOCOL (This);

  //
  // Check the new found network interface.
  //
  if (RestExInstance->NetworkInterfaceInstances != NULL) {
    FreePool (RestExInstance->NetworkInterfaceInstances);
    RestExInstance->NetworkInterfaceInstances = NULL;
  }

  ThisNetworkInterface = (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE *)AllocateZeroPool (sizeof (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE) * mNumNetworkInterface);
  if (ThisNetworkInterface == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  *NetworkIntfInstances = ThisNetworkInterface;

  RestExInstance->NetworkInterfaceInstances = ThisNetworkInterface;
  RestExInstance->NumberOfNetworkInterfaces = 0;

  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;
    RestExInstance->NumberOfNetworkInterfaces++;
    if (IsNodeAtEnd (&mEfiRedfishDiscoverNetworkInterface, &ThisNetworkInterfaceIntn->Entry)) {
      break;
    }

    ThisNetworkInterfaceIntn = (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *)GetNextNode (&mEfiRedfishDiscoverNetworkInterface, &ThisNetworkInterfaceIntn->Entry);
    ThisNetworkInterface++;
  }

  *NumberOfNetworkIntfs = RestExInstance->NumberOfNetworkInterfaces;

  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 corresponding
  EFI REST EX instance installed on it. Each REST EX instance is a child instance which
  created through EFI REST EX service protocol 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;
  BOOLEAN                                          NewInstance;
  UINTN                                            NumNetworkInterfaces;
  UINTN                                            NetworkInterfacesIndex;
  EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL  *TargetNetworkInterfaceInternal;

  DEBUG ((DEBUG_MANAGEABILITY, "%a:Entry.\n", __func__));

  //
  // Validate parameters.
  //
  if ((ImageHandle == NULL) || (Token == NULL) || ((Flags & ~EFI_REDFISH_DISCOVER_VALIDATION) == 0)) {
    DEBUG ((DEBUG_ERROR, "%a:Invalid parameters.\n", __func__));
    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", __func__));
      return EFI_UNSUPPORTED;
    }
  }

  for (NetworkInterfacesIndex = 0; NetworkInterfacesIndex < NumNetworkInterfaces; NetworkInterfacesIndex++) {
    Status1     = 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_MANAGEABILITY, "%a:Create new EFI_REDFISH_DISCOVERED_INTERNAL_INSTANCE.\n", __func__));
      Instance = (EFI_REDFISH_DISCOVERED_INTERNAL_INSTANCE *)AllocateZeroPool (sizeof (EFI_REDFISH_DISCOVERED_INTERNAL_INSTANCE));
      if (Instance == NULL) {
        DEBUG ((DEBUG_ERROR, "%a:Memory allocation fail.\n", __func__));
        return EFI_OUT_OF_RESOURCES;
      }

      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_MANAGEABILITY, "%a:Acquire Redfish service on network interface MAC address:%s.\n", __func__, TargetNetworkInterfaceInternal->StrMacAddr));
    } else {
      DEBUG ((DEBUG_MANAGEABILITY, "%a:WARNING: No MAC address on this network interface.\n", __func__));
    }

    Instance->DiscoverToken = Token; // Always use the latest Token passed by caller.
    if ((Flags & EFI_REDFISH_DISCOVER_HOST_INTERFACE) != 0) {
      DEBUG ((DEBUG_MANAGEABILITY, "%a:Redfish HOST interface discovery.\n", __func__));
      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", __func__));
      return EFI_UNSUPPORTED;
    } else {
      if (EFI_ERROR (Status1)) {
        if (NewInstance) {
          FreePool ((VOID *)Instance);
        }

        DEBUG ((DEBUG_ERROR, "%a:Something wrong on Redfish service discovery Status1=%r.\n", __func__, Status1));
      } 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 suppoted 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", __func__));
    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;
  }
}

/**
  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 destroy network interface


  @param[in]  ThisNetworkInterface EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL instance.

  @retval EFI_STATUS
**/
EFI_STATUS
DestroyRedfishNetworkInterface (
  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;
  UINTN       ListCount;

  ListCount = (sizeof (gRequiredProtocol) / sizeof (REDFISH_DISCOVER_REQUIRED_PROTOCOL));
  for (Index = 0; Index < ListCount; 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)) {
        if (Index == ListCount - 1) {
          DEBUG ((DEBUG_ERROR, "%a: all required protocols are found on this controller handle: %p.\n", __func__, ControllerHandle));
          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;
      CopyGuid (&NetworkInterface->NetworkInterfaceProtocolInfo.ProtocolGuid, gRequiredProtocol[Index].RequiredProtocolGuid);
      CopyGuid (&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 client 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 protocol is discovered.
          // This ensures EFI REST EX is ready while the consumer of EFI_REDFISH_DISCOVER_PROTOCOL
          // acquires Redfish service over network interface.

          if (!NewNetworkInterfaceInstalled) {
            NetworkInterface = GetTargetNetworkInterfaceInternalByController (ControllerHandle);
            if (NetworkInterface == NULL) {
              DEBUG ((DEBUG_ERROR, "%a: Can't find network interface by ControllerHandle\n", __func__));
              return Status;
            }
          }

          NewNetworkInterfaceInstalled                       = FALSE;
          NetworkInterface->EfiRedfishDiscoverProtocolHandle = NULL;

          RestExInstance->Signature = EFI_REDFISH_DISCOVER_DATA_SIGNATURE;

          RestExInstance->RedfishDiscoverProtocol.GetNetworkInterfaceList    = RedfishServiceGetNetworkInterface;
          RestExInstance->RedfishDiscoverProtocol.AcquireRedfishService      = RedfishServiceAcquireService;
          RestExInstance->RedfishDiscoverProtocol.AbortAcquireRedfishService = RedfishServiceAbortAcquire;
          RestExInstance->RedfishDiscoverProtocol.ReleaseRedfishService      = RedfishServiceReleaseService;

          Status = gBS->InstallProtocolInterface (
                          &NetworkInterface->EfiRedfishDiscoverProtocolHandle,
                          &gEfiRedfishDiscoverProtocolGuid,
                          EFI_NATIVE_INTERFACE,
                          (VOID *)&RestExInstance->RedfishDiscoverProtocol
                          );
          if (EFI_ERROR (Status)) {
            DEBUG ((DEBUG_ERROR, "%a: Fail to install EFI_REDFISH_DISCOVER_PROTOCOL\n", __func__));
          }
        } else {
          DEBUG ((DEBUG_MANAGEABILITY, "%a: Not REST EX, continue with next\n", __func__));
          Index++;
          if (Index == (sizeof (gRequiredProtocol) / sizeof (REDFISH_DISCOVER_REQUIRED_PROTOCOL))) {
            break;
          }

          continue;
        }
      }

      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_DEVICE_ERROR;
}

/**
  Close the protocol opened for Redfish discovery. This function also destroy
  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                Protocol is closed successfully.
  @retval Others                     Protocol 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                   Failed 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;
  EFI_REDFISH_DISCOVER_PROTOCOL                    *RedfishDiscoverProtocol;

  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 = DestroyRedfishNetworkInterface (ThisNetworkInterface);
            }

            gBS->RestoreTPL (OldTpl);

            //
            // Disconnect EFI Redfish discover driver controller to notify the
            // client which uses .EFI Redfish discover protocol.
            //
            if (DiscoverProtocolHandle != NULL) {
              Status = gBS->HandleProtocol (
                              DiscoverProtocolHandle,
                              &gEfiRedfishDiscoverProtocolGuid,
                              (VOID **)&RedfishDiscoverProtocol
                              );
              if (!EFI_ERROR (Status)) {
                RestExInstance = EFI_REDFISH_DISOVER_DATA_FROM_DISCOVER_PROTOCOL (RedfishDiscoverProtocol);
                //
                // Stop Redfish service discovery.
                //
                RedfishDiscoverProtocol->AbortAcquireRedfishService (
                                           RedfishDiscoverProtocol,
                                           RestExInstance->NetworkInterfaceInstances
                                           );

                gBS->DisconnectController (DiscoverProtocolHandle, NULL, NULL);
                Status = gBS->UninstallProtocolInterface (
                                DiscoverProtocolHandle,
                                &gEfiRedfishDiscoverProtocolGuid,
                                (VOID *)&RestExInstance->RedfishDiscoverProtocol
                                );
              }
            }

            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 failed 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 protocol 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;
}
