]> git.proxmox.com Git - mirror_edk2.git/commitdiff
EmulatorPkg/RedfishPlatformHostInterfaceLib library
authorAbner Chang <abner.chang@hpe.com>
Thu, 3 Dec 2020 05:00:14 +0000 (13:00 +0800)
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
Thu, 3 Dec 2020 07:54:44 +0000 (07:54 +0000)
BZ:
https://bugzilla.tianocore.org/show_bug.cgi?id=3102

Platform specific implementation of providing
Redfish host interface information.

Signed-off-by: Jiaxin Wu <jiaxin.wu@intel.com>
Signed-off-by: Ting Ye <ting.ye@intel.com>
Signed-off-by: Siyuan Fu <siyuan.fu@intel.com>
Signed-off-by: Fan Wang <fan.wang@intel.com>
Signed-off-by: Abner Chang <abner.chang@hpe.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Andrew Fish <afish@apple.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Nickle Wang <nickle.wang@hpe.com>
Cc: Peter O'Hanley <peter.ohanley@hpe.com>
Acked-by: Ray Ni <ray.ni@intel.com>
EmulatorPkg/EmulatorPkg.dec
EmulatorPkg/Library/RedfishPlatformHostInterfaceLib/RedfishPlatformHostInterfaceLib.c [new file with mode: 0644]
EmulatorPkg/Library/RedfishPlatformHostInterfaceLib/RedfishPlatformHostInterfaceLib.inf [new file with mode: 0644]

index 064f963c72c6bc3e1b9fc6d80d31faaee0b65276..5d7fe6473e35a47b0754ba665124efb819fa7ce5 100644 (file)
@@ -46,6 +46,7 @@
   gEmuSystemConfigGuid       = { 0xF8626165, 0x6CEB, 0x924A, { 0xBA, 0xFC, 0xF1, 0x3A, 0xB9, 0xD6, 0x57, 0x28 } }\r
   gEmuVirtualDisksGuid       = { 0xf2ba331a, 0x8985, 0x11db, { 0xa4, 0x06, 0x00, 0x40, 0xd0, 0x2b, 0x18, 0x35 } }\r
   gEmuPhysicalDisksGuid      = { 0xf2bdcc96, 0x8985, 0x11db, { 0x87, 0x19, 0x00, 0x40, 0xd0, 0x2b, 0x18, 0x35 } }\r
+  gEmuRedfishServiceGuid     = { 0x3fb208ac, 0x2185, 0x498c, { 0xbf, 0x46, 0xdc, 0x23, 0xda, 0x58, 0x7b, 0x55 } }\r
 \r
 [PcdsFeatureFlag]\r
   ## If TRUE, if symbols only load on breakpoints and gdb entry\r
diff --git a/EmulatorPkg/Library/RedfishPlatformHostInterfaceLib/RedfishPlatformHostInterfaceLib.c b/EmulatorPkg/Library/RedfishPlatformHostInterfaceLib/RedfishPlatformHostInterfaceLib.c
new file mode 100644 (file)
index 0000000..4e7bb65
--- /dev/null
@@ -0,0 +1,528 @@
+/** @file\r
+  PCI/PCIe network interface instace of RedfishPlatformHostInterfaceLib\r
+\r
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>\r
+  (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>\r
+\r
+  SPDX-License-Identifier: BSD-2-Clause-Patent\r
+\r
+**/\r
+\r
+#include <Uefi.h>\r
+#include <Library/BaseLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/DevicePathLib.h>\r
+#include <Library/MemoryAllocationLib.h>\r
+#include <Library/PrintLib.h>\r
+#include <Library/RedfishHostInterfaceLib.h>\r
+#include <Library/UefiLib.h>\r
+#include <Library/UefiBootServicesTableLib.h>\r
+#include <Library/UefiRuntimeServicesTableLib.h>\r
+\r
+#include <Pcd/RestExServiceDevicePath.h>\r
+#include <Guid/GlobalVariable.h>\r
+\r
+#define VERBOSE_COLUME_SIZE  (16)\r
+\r
+REDFISH_OVER_IP_PROTOCOL_DATA  *mRedfishOverIpProtocolData;\r
+UINT8 mRedfishProtocolDataSize;\r
+\r
+/**\r
+  Get the MAC address of NIC.\r
+\r
+  @param[out] MacAddress      Pointer to retrieve MAC address\r
+\r
+  @retval   EFI_SUCCESS      MAC address is returned in MacAddress\r
+\r
+**/\r
+EFI_STATUS\r
+GetMacAddressInformation (\r
+  OUT EFI_MAC_ADDRESS *MacAddress\r
+  )\r
+{\r
+  MAC_ADDR_DEVICE_PATH                     *Mac;\r
+  REST_EX_SERVICE_DEVICE_PATH_DATA         *RestExServiceDevicePathData;\r
+  EFI_DEVICE_PATH_PROTOCOL                 *RestExServiceDevicePath;\r
+  MAC_ADDR_DEVICE_PATH                     *MacAddressDevicePath;\r
+\r
+  Mac = NULL;\r
+  RestExServiceDevicePathData  = NULL;\r
+  RestExServiceDevicePath      = NULL;\r
+\r
+  RestExServiceDevicePathData = (REST_EX_SERVICE_DEVICE_PATH_DATA *)PcdGetPtr(PcdRedfishRestExServiceDevicePath);\r
+  if (RestExServiceDevicePathData == NULL ||\r
+      RestExServiceDevicePathData->DevicePathNum == 0 ||\r
+      !IsDevicePathValid (RestExServiceDevicePathData->DevicePath, 0)) {\r
+    return EFI_NOT_FOUND;\r
+  }\r
+\r
+  RestExServiceDevicePath = RestExServiceDevicePathData->DevicePath;\r
+  if (RestExServiceDevicePathData->DevicePathMatchMode != DEVICE_PATH_MATCH_MAC_NODE) {\r
+    return EFI_NOT_FOUND;\r
+  }\r
+\r
+  //\r
+  // Find Mac DevicePath Node.\r
+  //\r
+  while (!IsDevicePathEnd (RestExServiceDevicePath) &&\r
+         ((DevicePathType (RestExServiceDevicePath) != MESSAGING_DEVICE_PATH) ||\r
+          (DevicePathSubType (RestExServiceDevicePath) != MSG_MAC_ADDR_DP))) {\r
+    RestExServiceDevicePath = NextDevicePathNode (RestExServiceDevicePath);\r
+  }\r
+\r
+  if (!IsDevicePathEnd (RestExServiceDevicePath)) {\r
+    MacAddressDevicePath = (MAC_ADDR_DEVICE_PATH *)RestExServiceDevicePath;\r
+    CopyMem ((VOID *)MacAddress, (VOID *)&MacAddressDevicePath->MacAddress, sizeof (EFI_MAC_ADDRESS));\r
+    return EFI_SUCCESS;\r
+  }\r
+  return EFI_NOT_FOUND;\r
+}\r
+\r
+/**\r
+  Get platform Redfish host interface device descriptor.\r
+\r
+  @param[out] DeviceType        Pointer to retrieve device type.\r
+  @param[out] DeviceDescriptor  Pointer to retrieve REDFISH_INTERFACE_DATA, caller has to free\r
+                                this memory using FreePool().\r
+  @retval EFI_SUCCESS     Device descriptor is returned successfully in DeviceDescriptor.\r
+  @retval EFI_NOT_FOUND   No Redfish host interface descriptor provided on this platform.\r
+  @retval Others          Fail to get device descriptor.\r
+**/\r
+EFI_STATUS\r
+RedfishPlatformHostInterfaceDeviceDescriptor (\r
+  OUT UINT8 *DeviceType,\r
+  OUT REDFISH_INTERFACE_DATA  **DeviceDescriptor\r
+)\r
+{\r
+  EFI_STATUS Status;\r
+  EFI_MAC_ADDRESS MacAddress;\r
+  REDFISH_INTERFACE_DATA *RedfishInterfaceData;\r
+  PCI_OR_PCIE_INTERFACE_DEVICE_DESCRIPTOR_V2 *ThisDeviceDescriptor;\r
+\r
+  RedfishInterfaceData = AllocateZeroPool (sizeof (PCI_OR_PCIE_INTERFACE_DEVICE_DESCRIPTOR_V2) + 1);\r
+  if (RedfishInterfaceData == NULL) {\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+  RedfishInterfaceData->DeviceType = REDFISH_HOST_INTERFACE_DEVICE_TYPE_PCI_PCIE_V2;\r
+  //\r
+  // Fill up device type information.\r
+  //\r
+  ThisDeviceDescriptor = (PCI_OR_PCIE_INTERFACE_DEVICE_DESCRIPTOR_V2 *)((UINT8 *)RedfishInterfaceData + 1);\r
+  ThisDeviceDescriptor->Length = sizeof (PCI_OR_PCIE_INTERFACE_DEVICE_DESCRIPTOR_V2) + 1;\r
+  Status = GetMacAddressInformation (&MacAddress);\r
+  if (EFI_ERROR (Status)) {\r
+    FreePool (RedfishInterfaceData);\r
+    return EFI_NOT_FOUND;\r
+  }\r
+  CopyMem ((VOID *)&ThisDeviceDescriptor->MacAddress, (VOID *)&MacAddress, sizeof (ThisDeviceDescriptor->MacAddress));\r
+  *DeviceType = REDFISH_HOST_INTERFACE_DEVICE_TYPE_PCI_PCIE_V2;\r
+  *DeviceDescriptor = RedfishInterfaceData;\r
+  return EFI_SUCCESS;\r
+}\r
+/**\r
+  Get platform Redfish host interface protocol data.\r
+  Caller should pass NULL in ProtocolRecord to retrive the first protocol record.\r
+  Then continuously pass previous ProtocolRecord for retrieving the next ProtocolRecord.\r
+\r
+  @param[out] ProtocolRecord     Pointer to retrieve the protocol record.\r
+                                 caller has to free the new protocol record returned from\r
+                                 this function using FreePool().\r
+  @param[in] IndexOfProtocolData The index of protocol data.\r
+\r
+  @retval EFI_SUCCESS     Protocol records are all returned.\r
+  @retval EFI_NOT_FOUND   No more protocol records.\r
+  @retval Others          Fail to get protocol records.\r
+**/\r
+EFI_STATUS\r
+RedfishPlatformHostInterfaceProtocolData (\r
+  OUT MC_HOST_INTERFACE_PROTOCOL_RECORD **ProtocolRecord,\r
+  IN UINT8  IndexOfProtocolData\r
+)\r
+{\r
+  MC_HOST_INTERFACE_PROTOCOL_RECORD *ThisProtocolRecord;\r
+\r
+  if (mRedfishOverIpProtocolData == 0) {\r
+    return EFI_NOT_FOUND;\r
+  }\r
+  if (IndexOfProtocolData == 0) {\r
+    //\r
+    // Return the first Redfish protocol data to caller. We only have\r
+    // one protocol data in this case.\r
+    //\r
+    ThisProtocolRecord = (MC_HOST_INTERFACE_PROTOCOL_RECORD *) AllocatePool (mRedfishProtocolDataSize + sizeof (MC_HOST_INTERFACE_PROTOCOL_RECORD) - 1);\r
+    ThisProtocolRecord->ProtocolType = MCHostInterfaceProtocolTypeRedfishOverIP;\r
+    ThisProtocolRecord->ProtocolTypeDataLen = mRedfishProtocolDataSize;\r
+    CopyMem ((VOID *)&ThisProtocolRecord->ProtocolTypeData, (VOID *)mRedfishOverIpProtocolData, mRedfishProtocolDataSize);\r
+    *ProtocolRecord = ThisProtocolRecord;\r
+    return EFI_SUCCESS;\r
+  }\r
+  return EFI_NOT_FOUND;\r
+}\r
+/**\r
+  Dump IPv4 address.\r
+\r
+  @param[in] Ip IPv4 address\r
+**/\r
+VOID\r
+InternalDumpIp4Addr (\r
+  IN EFI_IPv4_ADDRESS   *Ip\r
+  )\r
+{\r
+  UINTN                 Index;\r
+\r
+  for (Index = 0; Index < 4; Index++) {\r
+    DEBUG ((DEBUG_VERBOSE, "%d", Ip->Addr[Index]));\r
+    if (Index < 3) {\r
+      DEBUG ((DEBUG_VERBOSE, "."));\r
+    }\r
+  }\r
+\r
+  DEBUG ((DEBUG_VERBOSE, "\n"));\r
+}\r
+/**\r
+  Dump IPv6 address.\r
+\r
+  @param[in] Ip IPv6 address\r
+**/\r
+VOID\r
+InternalDumpIp6Addr (\r
+  IN EFI_IPv6_ADDRESS   *Ip\r
+  )\r
+{\r
+  UINTN Index;\r
+\r
+  for (Index = 0; Index < 16; Index++) {\r
+    if (Ip->Addr[Index] != 0) {\r
+      DEBUG ((DEBUG_VERBOSE, "%x", Ip->Addr[Index]));\r
+    }\r
+    Index++;\r
+\r
+    if (Index > 15) {\r
+      return;\r
+    }\r
+\r
+    if (((Ip->Addr[Index] & 0xf0) == 0) && (Ip->Addr[Index - 1] != 0)) {\r
+      DEBUG ((DEBUG_VERBOSE, "0"));\r
+    }\r
+    DEBUG ((DEBUG_VERBOSE, "%x", Ip->Addr[Index]));\r
+\r
+    if (Index < 15) {\r
+      DEBUG ((DEBUG_VERBOSE, ":"));\r
+    }\r
+  }\r
+  DEBUG ((DEBUG_VERBOSE, "\n"));\r
+}\r
+/**\r
+  Dump data\r
+\r
+  @param[in] Data Pointer to data.\r
+  @param[in] Size size of data to dump.\r
+**/\r
+VOID\r
+InternalDumpData (\r
+  IN UINT8  *Data,\r
+  IN UINTN  Size\r
+  )\r
+{\r
+  UINTN  Index;\r
+  for (Index = 0; Index < Size; Index++) {\r
+    DEBUG ((DEBUG_VERBOSE, "%02x ", (UINTN)Data[Index]));\r
+  }\r
+}\r
+/**\r
+  Dump hex data\r
+\r
+  @param[in] Data Pointer to hex data.\r
+  @param[in] Size size of hex data to dump.\r
+**/\r
+VOID\r
+InternalDumpHex (\r
+  IN UINT8  *Data,\r
+  IN UINTN  Size\r
+  )\r
+{\r
+  UINTN   Index;\r
+  UINTN   Count;\r
+  UINTN   Left;\r
+\r
+  Count = Size / VERBOSE_COLUME_SIZE;\r
+  Left  = Size % VERBOSE_COLUME_SIZE;\r
+  for (Index = 0; Index < Count; Index++) {\r
+    InternalDumpData (Data + Index * VERBOSE_COLUME_SIZE, VERBOSE_COLUME_SIZE);\r
+    DEBUG ((DEBUG_VERBOSE, "\n"));\r
+  }\r
+\r
+  if (Left != 0) {\r
+    InternalDumpData (Data + Index * VERBOSE_COLUME_SIZE, Left);\r
+    DEBUG ((DEBUG_VERBOSE, "\n"));\r
+  }\r
+\r
+  DEBUG ((DEBUG_VERBOSE, "\n"));\r
+}\r
+/**\r
+  Dump Redfish over IP protocol data\r
+\r
+  @param[in] RedfishProtocolData     Pointer to REDFISH_OVER_IP_PROTOCOL_DATA\r
+  @param[in] RedfishProtocolDataSize size of data to dump.\r
+**/\r
+VOID\r
+DumpRedfishIpProtocolData (\r
+  IN REDFISH_OVER_IP_PROTOCOL_DATA   *RedfishProtocolData,\r
+  IN UINT8                           RedfishProtocolDataSize\r
+  )\r
+{\r
+  CHAR16 Hostname[16];\r
+\r
+  DEBUG ((DEBUG_VERBOSE, "RedfishProtocolData: \n"));\r
+  InternalDumpHex ((UINT8 *) RedfishProtocolData, RedfishProtocolDataSize);\r
+\r
+  DEBUG ((DEBUG_VERBOSE, "Parsing as below: \n"));\r
+\r
+  DEBUG ((DEBUG_VERBOSE, "RedfishProtocolData->ServiceUuid - %g\n", &(RedfishProtocolData->ServiceUuid)));\r
+\r
+  DEBUG ((DEBUG_VERBOSE, "RedfishProtocolData->HostIpAssignmentType - %d\n", RedfishProtocolData->HostIpAssignmentType));\r
+\r
+  DEBUG ((DEBUG_VERBOSE, "RedfishProtocolData->HostIpAddressFormat - %d\n", RedfishProtocolData->HostIpAddressFormat));\r
+\r
+  DEBUG ((DEBUG_VERBOSE, "RedfishProtocolData->HostIpAddress: \n"));\r
+  if (RedfishProtocolData->HostIpAddressFormat == 0x01) {\r
+    InternalDumpIp4Addr ((EFI_IPv4_ADDRESS *) (RedfishProtocolData->HostIpAddress));\r
+  } else {\r
+    InternalDumpIp6Addr ((EFI_IPv6_ADDRESS *) (RedfishProtocolData->HostIpAddress));\r
+  }\r
+\r
+  DEBUG ((DEBUG_VERBOSE, "RedfishProtocolData->HostIpMask: \n"));\r
+  if (RedfishProtocolData->HostIpAddressFormat == 0x01) {\r
+    InternalDumpIp4Addr ((EFI_IPv4_ADDRESS *) (RedfishProtocolData->HostIpMask));\r
+  } else {\r
+    InternalDumpIp6Addr ((EFI_IPv6_ADDRESS *) (RedfishProtocolData->HostIpMask));\r
+  }\r
+\r
+  DEBUG ((DEBUG_VERBOSE, "RedfishProtocolData->RedfishServiceIpDiscoveryType - %d\n", RedfishProtocolData->RedfishServiceIpDiscoveryType));\r
+\r
+  DEBUG ((DEBUG_VERBOSE, "RedfishProtocolData->RedfishServiceIpAddressFormat - %d\n", RedfishProtocolData->RedfishServiceIpAddressFormat));\r
+\r
+  DEBUG ((DEBUG_VERBOSE, "RedfishProtocolData->RedfishServiceIpAddress: \n"));\r
+  if (RedfishProtocolData->RedfishServiceIpAddressFormat == 0x01) {\r
+    InternalDumpIp4Addr ((EFI_IPv4_ADDRESS *) (RedfishProtocolData->RedfishServiceIpAddress));\r
+  } else {\r
+    InternalDumpIp6Addr ((EFI_IPv6_ADDRESS *) (RedfishProtocolData->RedfishServiceIpAddress));\r
+  }\r
+\r
+  DEBUG ((DEBUG_VERBOSE, "RedfishProtocolData->RedfishServiceIpMask: \n"));\r
+  if (RedfishProtocolData->RedfishServiceIpAddressFormat == 0x01) {\r
+    InternalDumpIp4Addr ((EFI_IPv4_ADDRESS *) (RedfishProtocolData->RedfishServiceIpMask));\r
+  } else {\r
+    InternalDumpIp6Addr ((EFI_IPv6_ADDRESS *) (RedfishProtocolData->RedfishServiceIpMask));\r
+  }\r
+\r
+  DEBUG ((DEBUG_VERBOSE, "RedfishProtocolData->RedfishServiceIpPort - %d\n", RedfishProtocolData->RedfishServiceIpPort));\r
+\r
+  DEBUG ((DEBUG_VERBOSE, "RedfishProtocolData->RedfishServiceVlanId - %d\n", RedfishProtocolData->RedfishServiceVlanId));\r
+\r
+  DEBUG ((DEBUG_VERBOSE, "RedfishProtocolData->RedfishServiceHostnameLength - %d\n", RedfishProtocolData->RedfishServiceHostnameLength));\r
+\r
+  AsciiStrToUnicodeStrS((CHAR8 *) RedfishProtocolData->RedfishServiceHostname, Hostname, sizeof (Hostname) / sizeof (Hostname[0]));\r
+  DEBUG ((DEBUG_VERBOSE, "RedfishProtocolData->RedfishServiceHostname - %s\n", Hostname));\r
+}\r
+\r
+/**\r
+  Get Redfish host interface protocol data from variale.\r
+\r
+  @param[out] RedfishProtocolData  Pointer to retrieve REDFISH_OVER_IP_PROTOCOL_DATA.\r
+  @param[out] RedfishProtocolDataSize  Size of REDFISH_OVER_IP_PROTOCOL_DATA.\r
+\r
+  @retval EFI_SUCESS   REDFISH_OVER_IP_PROTOCOL_DATA is returned successfully.\r
+**/\r
+EFI_STATUS\r
+GetRedfishRecordFromVariable (\r
+  OUT REDFISH_OVER_IP_PROTOCOL_DATA   **RedfishProtocolData,\r
+  OUT UINT8 *RedfishProtocolDataSize\r
+  )\r
+{\r
+  EFI_STATUS                      Status;\r
+  UINT8                           HostIpAssignmentType;\r
+  UINTN                           HostIpAssignmentTypeSize;\r
+  EFI_IPv4_ADDRESS                HostIpAddress;\r
+  UINTN                           IPv4DataSize;\r
+  EFI_IPv4_ADDRESS                HostIpMask;\r
+  EFI_IPv4_ADDRESS                RedfishServiceIpAddress;\r
+  EFI_IPv4_ADDRESS                RedfishServiceIpMask;\r
+  UINT16                          RedfishServiceIpPort;\r
+  UINTN                           IpPortDataSize;\r
+  UINT8                           HostNameSize;\r
+  CHAR8                           RedfishHostName[20];\r
+\r
+  if (RedfishProtocolData == NULL || RedfishProtocolDataSize == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  //\r
+  // 1. Retrieve Address Information from variable.\r
+  //\r
+  Status = gRT->GetVariable (\r
+                  L"HostIpAssignmentType",\r
+                  &gEmuRedfishServiceGuid,\r
+                  NULL,\r
+                  &HostIpAssignmentTypeSize,\r
+                  &HostIpAssignmentType\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    DEBUG ((DEBUG_ERROR, "RedfishPlatformDxe: GetVariable HostIpAssignmentType - %r\n", Status));\r
+    return Status;\r
+  }\r
+\r
+  IPv4DataSize = sizeof (EFI_IPv4_ADDRESS);\r
+  if (HostIpAssignmentType == 1 ) {\r
+    Status = gRT->GetVariable (\r
+                    L"HostIpAddress",\r
+                    &gEmuRedfishServiceGuid,\r
+                    NULL,\r
+                    &IPv4DataSize,\r
+                    &HostIpAddress\r
+                    );\r
+    if (EFI_ERROR (Status)) {\r
+      DEBUG ((DEBUG_ERROR, "RedfishPlatformDxe: GetVariable HostIpAddress - %r\n", Status));\r
+      return Status;\r
+    }\r
+\r
+    Status = gRT->GetVariable (\r
+                    L"HostIpMask",\r
+                    &gEmuRedfishServiceGuid,\r
+                    NULL,\r
+                    &IPv4DataSize,\r
+                    &HostIpMask\r
+                    );\r
+    if (EFI_ERROR (Status)) {\r
+      DEBUG ((DEBUG_ERROR, "RedfishPlatformDxe: GetVariable HostIpMask - %r\n", Status));\r
+      return Status;\r
+    }\r
+  }\r
+\r
+  Status = gRT->GetVariable (\r
+                  L"RedfishServiceIpAddress",\r
+                  &gEmuRedfishServiceGuid,\r
+                  NULL,\r
+                  &IPv4DataSize,\r
+                  &RedfishServiceIpAddress\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    DEBUG ((DEBUG_ERROR, "RedfishPlatformDxe: GetVariable RedfishServiceIpAddress - %r\n", Status));\r
+    return Status;\r
+  }\r
+\r
+  Status = gRT->GetVariable (\r
+                  L"RedfishServiceIpMask",\r
+                  &gEmuRedfishServiceGuid,\r
+                  NULL,\r
+                  &IPv4DataSize,\r
+                  &RedfishServiceIpMask\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    DEBUG ((DEBUG_ERROR, "RedfishPlatformDxe: GetVariable RedfishServiceIpMask - %r\n", Status));\r
+    return Status;\r
+  }\r
+\r
+  Status = gRT->GetVariable (\r
+                  L"RedfishServiceIpPort",\r
+                  &gEmuRedfishServiceGuid,\r
+                  NULL,\r
+                  &IpPortDataSize,\r
+                  &RedfishServiceIpPort\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    DEBUG ((DEBUG_ERROR, "RedfishPlatformDxe: GetVariable RedfishServiceIpPort - %r\n", Status));\r
+    return Status;\r
+  }\r
+\r
+  AsciiSPrint (\r
+    RedfishHostName,\r
+    sizeof (RedfishHostName),\r
+    "%d.%d.%d.%d",\r
+    RedfishServiceIpAddress.Addr[0],\r
+    RedfishServiceIpAddress.Addr[1],\r
+    RedfishServiceIpAddress.Addr[2],\r
+    RedfishServiceIpAddress.Addr[3]\r
+    );\r
+\r
+  HostNameSize = (UINT8) AsciiStrLen (RedfishHostName) + 1;\r
+\r
+  //\r
+  // 2. Protocol Data Size.\r
+  //\r
+  *RedfishProtocolDataSize = sizeof (REDFISH_OVER_IP_PROTOCOL_DATA) - 1 + HostNameSize;\r
+\r
+  //\r
+  // 3. Protocol Data.\r
+  //\r
+  *RedfishProtocolData = (REDFISH_OVER_IP_PROTOCOL_DATA *) AllocateZeroPool (*RedfishProtocolDataSize);\r
+  if (*RedfishProtocolData == NULL) {\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+\r
+  CopyGuid (&(*RedfishProtocolData)->ServiceUuid, &gEmuRedfishServiceGuid);\r
+\r
+  (*RedfishProtocolData)->HostIpAssignmentType = HostIpAssignmentType;\r
+  (*RedfishProtocolData)->HostIpAddressFormat = 1;   // Only support IPv4\r
+\r
+  if (HostIpAssignmentType == 1 ) {\r
+    (*RedfishProtocolData)->HostIpAddress[0] = HostIpAddress.Addr[0];\r
+    (*RedfishProtocolData)->HostIpAddress[1] = HostIpAddress.Addr[1];\r
+    (*RedfishProtocolData)->HostIpAddress[2] = HostIpAddress.Addr[2];\r
+    (*RedfishProtocolData)->HostIpAddress[3] = HostIpAddress.Addr[3];\r
+\r
+    (*RedfishProtocolData)->HostIpMask[0] = HostIpMask.Addr[0];\r
+    (*RedfishProtocolData)->HostIpMask[1] = HostIpMask.Addr[1];\r
+    (*RedfishProtocolData)->HostIpMask[2] = HostIpMask.Addr[2];\r
+    (*RedfishProtocolData)->HostIpMask[3] = HostIpMask.Addr[3];\r
+  }\r
+\r
+  (*RedfishProtocolData)->RedfishServiceIpDiscoveryType = 1;  // Use static IP address\r
+  (*RedfishProtocolData)->RedfishServiceIpAddressFormat = 1;  // Only support IPv4\r
+\r
+  (*RedfishProtocolData)->RedfishServiceIpAddress[0] = RedfishServiceIpAddress.Addr[0];\r
+  (*RedfishProtocolData)->RedfishServiceIpAddress[1] = RedfishServiceIpAddress.Addr[1];\r
+  (*RedfishProtocolData)->RedfishServiceIpAddress[2] = RedfishServiceIpAddress.Addr[2];\r
+  (*RedfishProtocolData)->RedfishServiceIpAddress[3] = RedfishServiceIpAddress.Addr[3];\r
+\r
+  (*RedfishProtocolData)->RedfishServiceIpMask[0] = RedfishServiceIpMask.Addr[0];\r
+  (*RedfishProtocolData)->RedfishServiceIpMask[1] = RedfishServiceIpMask.Addr[1];\r
+  (*RedfishProtocolData)->RedfishServiceIpMask[2] = RedfishServiceIpMask.Addr[2];\r
+  (*RedfishProtocolData)->RedfishServiceIpMask[3] = RedfishServiceIpMask.Addr[3];\r
+\r
+  (*RedfishProtocolData)->RedfishServiceIpPort = RedfishServiceIpPort;\r
+  (*RedfishProtocolData)->RedfishServiceVlanId = 0xffffffff;\r
+\r
+  (*RedfishProtocolData)->RedfishServiceHostnameLength = HostNameSize;\r
+  AsciiStrCpyS ((CHAR8 *) ((*RedfishProtocolData)->RedfishServiceHostname), HostNameSize, RedfishHostName);\r
+\r
+  return Status;\r
+}\r
+\r
+/**\r
+  Construct Redfish host interface protocol data.\r
+\r
+  @param ImageHandle     The image handle.\r
+  @param SystemTable     The system table.\r
+\r
+  @retval  EFI_SUCEESS  Install Boot manager menu success.\r
+  @retval  Other        Return error status.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+RedfishPlatformHostInterfaceConstructor (\r
+  IN EFI_HANDLE                            ImageHandle,\r
+  IN EFI_SYSTEM_TABLE                      *SystemTable\r
+)\r
+{\r
+  EFI_STATUS Status;\r
+\r
+  Status = GetRedfishRecordFromVariable (&mRedfishOverIpProtocolData, &mRedfishProtocolDataSize);\r
+  DEBUG ((DEBUG_INFO, "%a: GetRedfishRecordFromVariable() - %r\n", __FUNCTION__, Status));\r
+  if (!EFI_ERROR (Status)) {\r
+    DumpRedfishIpProtocolData (mRedfishOverIpProtocolData, mRedfishProtocolDataSize);\r
+  }\r
+  return EFI_SUCCESS;\r
+}\r
diff --git a/EmulatorPkg/Library/RedfishPlatformHostInterfaceLib/RedfishPlatformHostInterfaceLib.inf b/EmulatorPkg/Library/RedfishPlatformHostInterfaceLib/RedfishPlatformHostInterfaceLib.inf
new file mode 100644 (file)
index 0000000..668a813
--- /dev/null
@@ -0,0 +1,47 @@
+## @file\r
+#  NULL instance of RedfishPlatformHostInterfaceLib\r
+#\r
+#  (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>\r
+#\r
+#  SPDX-License-Identifier: BSD-2-Clause-Patent\r
+#\r
+##\r
+\r
+[Defines]\r
+  INF_VERSION                    = 0x0001000b\r
+  BASE_NAME                      = RedfishPlatformHostInterfaceLib\r
+  FILE_GUID                      = D5ECB7F2-4906-94E2-45B1-31BF4FD90122\r
+  MODULE_TYPE                    = DXE_DRIVER\r
+  VERSION_STRING                 = 1.0\r
+  LIBRARY_CLASS                  = RedfishPlatformHostInterfaceLib\r
+  CONSTRUCTOR                    = RedfishPlatformHostInterfaceConstructor\r
+#\r
+#  VALID_ARCHITECTURES           = IA32 X64\r
+#\r
+\r
+[Sources]\r
+  RedfishPlatformHostInterfaceLib.c\r
+\r
+[Packages]\r
+  EmulatorPkg/EmulatorPkg.dec\r
+  MdePkg/MdePkg.dec\r
+  MdeModulePkg/MdeModulePkg.dec\r
+  RedfishPkg/RedfishPkg.dec\r
+\r
+[LibraryClasses]\r
+  BaseLib\r
+  BaseMemoryLib\r
+  DebugLib\r
+  MemoryAllocationLib\r
+  PcdLib\r
+  UefiLib\r
+\r
+[Pcd]\r
+  gEfiRedfishPkgTokenSpaceGuid.PcdRedfishRestExServiceDevicePath         ## CONSUMES\r
+\r
+[Guids]\r
+  gEmuRedfishServiceGuid\r
+\r
+[Depex]\r
+  gEfiVariableArchProtocolGuid AND\r
+  gEfiVariableWriteArchProtocolGuid\r