]> git.proxmox.com Git - mirror_edk2.git/commitdiff
RedfishPkg/RestJsonStructureDxe: EFI REST JSON Structure Protocol
authorAbner Chang <abner.chang@hpe.com>
Thu, 8 Oct 2020 14:19:12 +0000 (22:19 +0800)
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
Mon, 2 Nov 2020 04:31:54 +0000 (04:31 +0000)
Implementation of EFI_REST_JSON_STRUCTURE_PROTOCOL, refer to UEFI spec
2.8 Section 29.7.3 EFI REST JSON Resource to C Structure Converter.

Signed-off-by: Abner Chang <abner.chang@hpe.com>
Cc: Jiaxin Wu <jiaxin.wu@intel.com>
Cc: Siyuan Fu <siyuan.fu@intel.com>
Cc: Fan Wang <fan.wang@intel.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Nickle Wang <nickle.wang@hpe.com>
Reviewed-by: Nickle Wang <nickle.wang@hpe.com>
RedfishPkg/RedfishPkg.dsc
RedfishPkg/RestJsonStructureDxe/RestJsonStructureDxe.c [new file with mode: 0644]
RedfishPkg/RestJsonStructureDxe/RestJsonStructureDxe.inf [new file with mode: 0644]
RedfishPkg/RestJsonStructureDxe/RestJsonStructureInternal.h [new file with mode: 0644]

index 8acadddefc6bfa325f2fb3794ed692489b92a745..f0c6740facdad078f8fefcf3f07bf584f0ec8ba4 100644 (file)
   DxeServicesTableLib|MdePkg/Library/DxeServicesTableLib/DxeServicesTableLib.inf\r
   DxeServicesLib|MdePkg/Library/DxeServicesLib/DxeServicesLib.inf\r
   ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf\r
+\r
+[LibraryClasses.ARM, LibraryClasses.AARCH64]\r
+  #\r
+  # This library provides the instrinsic functions generated by a given compiler.\r
+  #\r
+  NULL|ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf\r
+  NULL|MdePkg/Library/BaseStackCheckLib/BaseStackCheckLib.inf\r
+  ArmSoftFloatLib|ArmPkg/Library/ArmSoftFloatLib/ArmSoftFloatLib.inf\r
+\r
+[Components]\r
+  RedfishPkg/RestJsonStructureDxe/RestJsonStructureDxe.inf\r
diff --git a/RedfishPkg/RestJsonStructureDxe/RestJsonStructureDxe.c b/RedfishPkg/RestJsonStructureDxe/RestJsonStructureDxe.c
new file mode 100644 (file)
index 0000000..a3f4cd3
--- /dev/null
@@ -0,0 +1,586 @@
+/** @file\r
+\r
+  The implementation of EFI REST Resource JSON to C structure convertor\r
+  Protocol.\r
+\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 <Protocol/RestJsonStructure.h>\r
+#include "RestJsonStructureInternal.h"\r
+\r
+LIST_ENTRY mRestJsonStructureList;\r
+EFI_HANDLE mProtocolHandle;\r
+\r
+/**\r
+  This function registers Restful resource interpreter for the\r
+  specific schema.\r
+\r
+  @param[in]    This                     This is the EFI_REST_JSON_STRUCTURE_PROTOCOL instance.\r
+  @param[in]    JsonStructureSupported   The type and version of REST JSON resource which this converter\r
+                                         supports.\r
+  @param[in]    ToStructure              The function to convert REST JSON resource to structure.\r
+  @param[in]    ToJson                   The function to convert REST JSON structure to JSON in text format.\r
+  @param[in]    DestroyStructure         Destroy REST JSON structure returned in ToStructure()  function.\r
+\r
+  @retval EFI_SUCCESS             Register successfully.\r
+  @retval Others                  Fail to register.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+RestJsonStructureRegister (\r
+  IN EFI_REST_JSON_STRUCTURE_PROTOCOL       *This,\r
+  IN EFI_REST_JSON_STRUCTURE_SUPPORTED      *JsonStructureSupported,\r
+  IN EFI_REST_JSON_STRUCTURE_TO_STRUCTURE   ToStructure,\r
+  IN EFI_REST_JSON_STRUCTURE_TO_JSON        ToJson,\r
+  IN EFI_REST_JSON_STRUCTURE_DESTORY_STRUCTURE DestroyStructure\r
+)\r
+{\r
+  UINTN NumberOfNS;\r
+  UINTN Index;\r
+  LIST_ENTRY *ThisList;\r
+  REST_JSON_STRUCTURE_INSTANCE *Instance;\r
+  EFI_REST_JSON_RESOURCE_TYPE_IDENTIFIER *CloneSupportedInterpId;\r
+  EFI_REST_JSON_STRUCTURE_SUPPORTED *ThisSupportedInterp;\r
+\r
+  if (This == NULL ||\r
+      ToStructure == NULL ||\r
+      ToJson == NULL ||\r
+      DestroyStructure == NULL ||\r
+      JsonStructureSupported == NULL\r
+      ) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  //\r
+  // Check how many name space interpreter can interpret.\r
+  //\r
+  ThisList = &JsonStructureSupported->NextSupportedRsrcInterp;\r
+  NumberOfNS = 1;\r
+  while (TRUE) {\r
+    if (ThisList->ForwardLink == &JsonStructureSupported->NextSupportedRsrcInterp) {\r
+      break;\r
+    } else {\r
+      ThisList = ThisList->ForwardLink;\r
+      NumberOfNS ++;\r
+    }\r
+  };\r
+\r
+  Instance =\r
+    (REST_JSON_STRUCTURE_INSTANCE *)AllocateZeroPool (sizeof (REST_JSON_STRUCTURE_INSTANCE) + NumberOfNS * sizeof (EFI_REST_JSON_RESOURCE_TYPE_IDENTIFIER));\r
+  if (Instance == NULL) {\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+  InitializeListHead (&Instance->NextRestJsonStructureInstance);\r
+  Instance->NumberOfNameSpaceToConvert = NumberOfNS;\r
+  Instance->SupportedRsrcIndentifier = (EFI_REST_JSON_RESOURCE_TYPE_IDENTIFIER *)((REST_JSON_STRUCTURE_INSTANCE *)Instance + 1);\r
+  //\r
+  // Copy supported resource identifer interpreter.\r
+  //\r
+  CloneSupportedInterpId = Instance->SupportedRsrcIndentifier;\r
+  ThisSupportedInterp = JsonStructureSupported;\r
+  for (Index = 0; Index < NumberOfNS; Index ++) {\r
+    CopyMem ((VOID *)CloneSupportedInterpId, (VOID *)&ThisSupportedInterp->RestResourceInterp, sizeof (EFI_REST_JSON_RESOURCE_TYPE_IDENTIFIER));\r
+    ThisSupportedInterp = (EFI_REST_JSON_STRUCTURE_SUPPORTED *)ThisSupportedInterp->NextSupportedRsrcInterp.ForwardLink;\r
+    CloneSupportedInterpId ++;\r
+  }\r
+  Instance->JsonToStructure = ToStructure;\r
+  Instance->StructureToJson = ToJson;\r
+  Instance->DestroyStructure = DestroyStructure;\r
+  InsertTailList (&mRestJsonStructureList, &Instance->NextRestJsonStructureInstance);\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  This function check if this interpreter instance support the given namesapce.\r
+\r
+  @param[in]    This                EFI_REST_JSON_STRUCTURE_PROTOCOL instance.\r
+  @param[in]    InterpreterInstance REST_JSON_STRUCTURE_INSTANCE\r
+  @param[in]    RsrcTypeIdentifier  Resource type identifier.\r
+  @param[in]    ResourceRaw         Given Restful resource.\r
+  @param[out]   RestJSonHeader      Property interpreted from given ResourceRaw.\r
+\r
+  @retval EFI_SUCCESS\r
+  @retval Others.\r
+\r
+**/\r
+EFI_STATUS\r
+InterpreterInstanceToStruct (\r
+  IN EFI_REST_JSON_STRUCTURE_PROTOCOL         *This,\r
+  IN REST_JSON_STRUCTURE_INSTANCE             *InterpreterInstance,\r
+  IN EFI_REST_JSON_RESOURCE_TYPE_IDENTIFIER   *RsrcTypeIdentifier OPTIONAL,\r
+  IN CHAR8                                    *ResourceRaw,\r
+  OUT EFI_REST_JSON_STRUCTURE_HEADER          **RestJSonHeader\r
+ )\r
+{\r
+  UINTN Index;\r
+  EFI_STATUS Status;\r
+  EFI_REST_JSON_RESOURCE_TYPE_IDENTIFIER *ThisSupportedRsrcTypeId;\r
+\r
+  if (This == NULL ||\r
+      InterpreterInstance == NULL ||\r
+      ResourceRaw == NULL ||\r
+      RestJSonHeader == NULL\r
+      ) {\r
+      return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  Status = EFI_UNSUPPORTED;\r
+  if (RsrcTypeIdentifier == NULL) {\r
+    //\r
+    // No resource type identifier, send to intepreter anyway.\r
+    // Interpreter may recognize this resource.\r
+    //\r
+    Status = InterpreterInstance->JsonToStructure (\r
+                This,\r
+                NULL,\r
+                ResourceRaw,\r
+                RestJSonHeader\r
+                );\r
+  } else {\r
+    //\r
+    // Check if the namesapce and version is supported by this interpreter.\r
+    //\r
+    ThisSupportedRsrcTypeId = InterpreterInstance->SupportedRsrcIndentifier;\r
+    for (Index = 0; Index < InterpreterInstance->NumberOfNameSpaceToConvert; Index ++){\r
+      if (AsciiStrCmp (\r
+            RsrcTypeIdentifier->NameSpace.ResourceTypeName,\r
+            ThisSupportedRsrcTypeId->NameSpace.ResourceTypeName) == 0){\r
+        if ((RsrcTypeIdentifier->NameSpace.MajorVersion == NULL) &&\r
+            (RsrcTypeIdentifier->NameSpace.MinorVersion == NULL) &&\r
+            (RsrcTypeIdentifier->NameSpace.ErrataVersion == NULL)\r
+            ) {\r
+          //\r
+          // Don't check version of this resource type identifier.\r
+          //\r
+          Status = InterpreterInstance->JsonToStructure (\r
+                      This,\r
+                      RsrcTypeIdentifier,\r
+                      ResourceRaw,\r
+                      RestJSonHeader\r
+                      );\r
+          break;\r
+        } else {\r
+          //\r
+          // Check version.\r
+          //\r
+          if ((AsciiStrCmp (\r
+                RsrcTypeIdentifier->NameSpace.MajorVersion,\r
+                ThisSupportedRsrcTypeId->NameSpace.MajorVersion) == 0) &&\r
+              (AsciiStrCmp (\r
+                RsrcTypeIdentifier->NameSpace.MinorVersion,\r
+                ThisSupportedRsrcTypeId->NameSpace.MinorVersion) == 0) &&\r
+              (AsciiStrCmp (\r
+                RsrcTypeIdentifier->NameSpace.ErrataVersion,\r
+                ThisSupportedRsrcTypeId->NameSpace.ErrataVersion) == 0)) {\r
+            Status = InterpreterInstance->JsonToStructure (\r
+                      This,\r
+                      RsrcTypeIdentifier,\r
+                      ResourceRaw,\r
+                      RestJSonHeader\r
+                      );\r
+            break;\r
+          }\r
+        }\r
+      }\r
+      ThisSupportedRsrcTypeId ++;\r
+    }\r
+  }\r
+  return Status;\r
+}\r
+/**\r
+  This function converts JSON C structure to JSON property.\r
+\r
+  @param[in]    This                 EFI_REST_JSON_STRUCTURE_PROTOCOL instance.\r
+  @param[in]    InterpreterInstance  REST_JSON_STRUCTURE_INSTANCE\r
+  @param[in]    RestJSonHeader       Resource type identifier.\r
+  @param[out]   ResourceRaw          Output in JSON text format.\r
+\r
+  @retval EFI_SUCCESS\r
+  @retval Others.\r
+\r
+**/\r
+EFI_STATUS\r
+InterpreterEfiStructToInstance (\r
+  IN EFI_REST_JSON_STRUCTURE_PROTOCOL   *This,\r
+  IN REST_JSON_STRUCTURE_INSTANCE       *InterpreterInstance,\r
+  IN EFI_REST_JSON_STRUCTURE_HEADER     *RestJSonHeader,\r
+  OUT CHAR8 **ResourceRaw\r
+)\r
+{\r
+  UINTN Index;\r
+  EFI_STATUS Status;\r
+  EFI_REST_JSON_RESOURCE_TYPE_IDENTIFIER *ThisSupportedRsrcTypeId;\r
+  EFI_REST_JSON_RESOURCE_TYPE_IDENTIFIER *RsrcTypeIdentifier;\r
+\r
+  if (This == NULL ||\r
+      InterpreterInstance == NULL ||\r
+      RestJSonHeader == NULL ||\r
+      ResourceRaw == NULL\r
+      ) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+  RsrcTypeIdentifier = &RestJSonHeader->JsonRsrcIdentifier;\r
+  if (RsrcTypeIdentifier == NULL ||\r
+      RsrcTypeIdentifier->NameSpace.ResourceTypeName == NULL ||\r
+      RsrcTypeIdentifier->NameSpace.MajorVersion == NULL ||\r
+      RsrcTypeIdentifier->NameSpace.MinorVersion == NULL ||\r
+      RsrcTypeIdentifier->NameSpace.ErrataVersion == NULL\r
+      ) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  //\r
+  // Check if the namesapce and version is supported by this interpreter.\r
+  //\r
+  Status = EFI_UNSUPPORTED;\r
+  ThisSupportedRsrcTypeId = InterpreterInstance->SupportedRsrcIndentifier;\r
+  for (Index = 0; Index < InterpreterInstance->NumberOfNameSpaceToConvert; Index ++){\r
+    if (AsciiStrCmp (\r
+          RsrcTypeIdentifier->NameSpace.ResourceTypeName,\r
+          ThisSupportedRsrcTypeId->NameSpace.ResourceTypeName) == 0){\r
+      //\r
+      // Check version.\r
+      //\r
+      if ((AsciiStrCmp (\r
+            RsrcTypeIdentifier->NameSpace.MajorVersion,\r
+            ThisSupportedRsrcTypeId->NameSpace.MajorVersion) == 0) &&\r
+          (AsciiStrCmp (\r
+            RsrcTypeIdentifier->NameSpace.MinorVersion,\r
+            ThisSupportedRsrcTypeId->NameSpace.MinorVersion) == 0) &&\r
+          (AsciiStrCmp (\r
+            RsrcTypeIdentifier->NameSpace.ErrataVersion,\r
+            ThisSupportedRsrcTypeId->NameSpace.ErrataVersion) == 0)) {\r
+        Status = InterpreterInstance->StructureToJson (\r
+                  This,\r
+                  RestJSonHeader,\r
+                  ResourceRaw\r
+                  );\r
+        break;\r
+      }\r
+    }\r
+    ThisSupportedRsrcTypeId ++;\r
+  }\r
+  return Status;\r
+}\r
+\r
+/**\r
+  This function destory REST property structure.\r
+\r
+  @param[in]    This                 EFI_REST_JSON_STRUCTURE_PROTOCOL instance.\r
+  @param[in]    InterpreterInstance  REST_JSON_STRUCTURE_INSTANCE\r
+  @param[in]    RestJSonHeader       Property interpreted from given ResourceRaw.\r
+\r
+  @retval EFI_SUCCESS\r
+  @retval Others.\r
+\r
+**/\r
+EFI_STATUS\r
+InterpreterInstanceDestoryJsonStruct (\r
+  IN EFI_REST_JSON_STRUCTURE_PROTOCOL       *This,\r
+  IN REST_JSON_STRUCTURE_INSTANCE           *InterpreterInstance,\r
+  IN EFI_REST_JSON_STRUCTURE_HEADER         *RestJSonHeader\r
+ )\r
+{\r
+  UINTN Index;\r
+  EFI_STATUS Status;\r
+  EFI_REST_JSON_RESOURCE_TYPE_IDENTIFIER *ThisSupportedRsrcTypeId;\r
+\r
+  if (This == NULL ||\r
+      InterpreterInstance == NULL ||\r
+      RestJSonHeader == NULL\r
+      ) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  Status = EFI_UNSUPPORTED;\r
+  //\r
+  // Check if the namesapce and version is supported by this interpreter.\r
+  //\r
+  ThisSupportedRsrcTypeId = InterpreterInstance->SupportedRsrcIndentifier;\r
+  for (Index = 0; Index < InterpreterInstance->NumberOfNameSpaceToConvert; Index ++){\r
+    if (AsciiStrCmp (\r
+          RestJSonHeader->JsonRsrcIdentifier.NameSpace.ResourceTypeName,\r
+          ThisSupportedRsrcTypeId->NameSpace.ResourceTypeName) == 0) {\r
+      if ((RestJSonHeader->JsonRsrcIdentifier.NameSpace.MajorVersion == NULL) &&\r
+          (RestJSonHeader->JsonRsrcIdentifier.NameSpace.MinorVersion == NULL) &&\r
+          (RestJSonHeader->JsonRsrcIdentifier.NameSpace.ErrataVersion == NULL)\r
+          ) {\r
+        //\r
+        // Don't check version of this resource type identifier.\r
+        //\r
+        Status = InterpreterInstance->DestroyStructure (\r
+                    This,\r
+                    RestJSonHeader\r
+                    );\r
+        break;\r
+      } else {\r
+        //\r
+        // Check version.\r
+        //\r
+        if ((AsciiStrCmp (\r
+              RestJSonHeader->JsonRsrcIdentifier.NameSpace.MajorVersion,\r
+              ThisSupportedRsrcTypeId->NameSpace.MajorVersion) == 0) &&\r
+            (AsciiStrCmp (\r
+              RestJSonHeader->JsonRsrcIdentifier.NameSpace.MinorVersion,\r
+              ThisSupportedRsrcTypeId->NameSpace.MinorVersion) == 0) &&\r
+            (AsciiStrCmp (\r
+              RestJSonHeader->JsonRsrcIdentifier.NameSpace.ErrataVersion,\r
+              ThisSupportedRsrcTypeId->NameSpace.ErrataVersion) == 0)) {\r
+          Status = InterpreterInstance->DestroyStructure (\r
+                    This,\r
+                    RestJSonHeader\r
+                    );\r
+          break;\r
+        }\r
+      }\r
+    }\r
+    ThisSupportedRsrcTypeId ++;\r
+  }\r
+  return Status;\r
+}\r
+\r
+/**\r
+  This function translates the given JSON text to JSON C Structure.\r
+\r
+  @param[in]    This                EFI_REST_JSON_STRUCTURE_PROTOCOL instance.\r
+  @param[in]    RsrcTypeIdentifier  Resource type identifier.\r
+  @param[in]    ResourceJsonText    Given Restful resource.\r
+  @param[out]   JsonStructure       Property interpreted from given ResourceRaw.\r
+\r
+  @retval EFI_SUCCESS\r
+  @retval Others.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+RestJsonStructureToStruct (\r
+  IN EFI_REST_JSON_STRUCTURE_PROTOCOL       *This,\r
+  IN EFI_REST_JSON_RESOURCE_TYPE_IDENTIFIER *RsrcTypeIdentifier OPTIONAL,\r
+  IN CHAR8                                  *ResourceJsonText,\r
+  OUT EFI_REST_JSON_STRUCTURE_HEADER        **JsonStructure\r
+)\r
+{\r
+  EFI_STATUS Status;\r
+  REST_JSON_STRUCTURE_INSTANCE *Instance;\r
+\r
+  if (This == NULL ||\r
+      ResourceJsonText == NULL ||\r
+      JsonStructure == NULL\r
+    ) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  if (IsListEmpty (&mRestJsonStructureList)) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+  Status = EFI_SUCCESS;\r
+  Instance = (REST_JSON_STRUCTURE_INSTANCE *)GetFirstNode (&mRestJsonStructureList);\r
+  while (TRUE) {\r
+    Status = InterpreterInstanceToStruct (\r
+                This,\r
+                Instance,\r
+                RsrcTypeIdentifier,\r
+                ResourceJsonText,\r
+                JsonStructure\r
+              );\r
+    if (!EFI_ERROR (Status)) {\r
+      break;\r
+    }\r
+    if (IsNodeAtEnd(&mRestJsonStructureList, &Instance->NextRestJsonStructureInstance)) {\r
+      Status = EFI_UNSUPPORTED;\r
+      break;\r
+    }\r
+    Instance = (REST_JSON_STRUCTURE_INSTANCE *)GetNextNode (&mRestJsonStructureList, &Instance->NextRestJsonStructureInstance);\r
+  };\r
+  return Status;\r
+}\r
+\r
+/**\r
+  This function destory REST property EFI structure which returned in\r
+  JsonToStructure().\r
+\r
+  @param[in]    This            EFI_REST_JSON_STRUCTURE_PROTOCOL instance.\r
+  @param[in]    RestJSonHeader  Property to destory.\r
+\r
+  @retval EFI_SUCCESS\r
+  @retval Others\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+RestJsonStructureDestroyStruct (\r
+  IN EFI_REST_JSON_STRUCTURE_PROTOCOL *This,\r
+  IN EFI_REST_JSON_STRUCTURE_HEADER  *RestJSonHeader\r
+)\r
+{\r
+  EFI_STATUS Status;\r
+  REST_JSON_STRUCTURE_INSTANCE *Instance;\r
+\r
+  if (This == NULL || RestJSonHeader == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  if (IsListEmpty (&mRestJsonStructureList)) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+  Status = EFI_SUCCESS;\r
+  Instance = (REST_JSON_STRUCTURE_INSTANCE *)GetFirstNode (&mRestJsonStructureList);\r
+  while (TRUE) {\r
+    Status = InterpreterInstanceDestoryJsonStruct (\r
+                This,\r
+                Instance,\r
+                RestJSonHeader\r
+              );\r
+    if (!EFI_ERROR (Status)) {\r
+      break;\r
+    }\r
+    if (IsNodeAtEnd(&mRestJsonStructureList, &Instance->NextRestJsonStructureInstance)) {\r
+      Status = EFI_UNSUPPORTED;\r
+      break;\r
+    }\r
+    Instance = (REST_JSON_STRUCTURE_INSTANCE *)GetNextNode (&mRestJsonStructureList, &Instance->NextRestJsonStructureInstance);\r
+  };\r
+  return Status;\r
+}\r
+\r
+/**\r
+  This function translates the given JSON C Structure to JSON text.\r
+\r
+  @param[in]    This            EFI_REST_JSON_STRUCTURE_PROTOCOL instance.\r
+  @param[in]    RestJSonHeader  Given Restful resource.\r
+  @param[out]   ResourceRaw     Resource in RESTfuls service oriented.\r
+\r
+  @retval EFI_SUCCESS\r
+  @retval Others             Fail to remove the entry\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+RestJsonStructureToJson (\r
+  IN EFI_REST_JSON_STRUCTURE_PROTOCOL *This,\r
+  IN EFI_REST_JSON_STRUCTURE_HEADER *RestJSonHeader,\r
+  OUT CHAR8 **ResourceRaw\r
+)\r
+{\r
+  EFI_STATUS Status;\r
+  REST_JSON_STRUCTURE_INSTANCE *Instance;\r
+\r
+  if (This == NULL || RestJSonHeader == NULL || ResourceRaw == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  if (IsListEmpty (&mRestJsonStructureList)) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+  Status = EFI_SUCCESS;\r
+  Instance = (REST_JSON_STRUCTURE_INSTANCE *)GetFirstNode (&mRestJsonStructureList);\r
+  while (TRUE) {\r
+    Status = InterpreterEfiStructToInstance (\r
+                This,\r
+                Instance,\r
+                RestJSonHeader,\r
+                ResourceRaw\r
+              );\r
+    if (!EFI_ERROR (Status)) {\r
+      break;\r
+    }\r
+    if (IsNodeAtEnd(&mRestJsonStructureList, &Instance->NextRestJsonStructureInstance)) {\r
+      Status = EFI_UNSUPPORTED;\r
+      break;\r
+    }\r
+    Instance = (REST_JSON_STRUCTURE_INSTANCE *)GetNextNode (&mRestJsonStructureList, &Instance->NextRestJsonStructureInstance);\r
+  };\r
+  return Status;\r
+}\r
+\r
+EFI_REST_JSON_STRUCTURE_PROTOCOL mRestJsonStructureProtocol = {\r
+  RestJsonStructureRegister,\r
+  RestJsonStructureToStruct,\r
+  RestJsonStructureToJson,\r
+  RestJsonStructureDestroyStruct\r
+};\r
+\r
+/**\r
+  This is the declaration of an EFI image entry point.\r
+\r
+  @param  ImageHandle           The firmware allocated handle for the UEFI image.\r
+  @param  SystemTable           A pointer to the EFI System Table.\r
+\r
+  @retval EFI_SUCCESS           The operation completed successfully.\r
+  @retval Others                An unexpected error occurred.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+RestJsonStructureEntryPoint (\r
+  IN EFI_HANDLE        ImageHandle,\r
+  IN EFI_SYSTEM_TABLE  *SystemTable\r
+  )\r
+{\r
+  EFI_STATUS Status;\r
+\r
+  InitializeListHead (&mRestJsonStructureList);\r
+  //\r
+  // Install the Restful Resource Interpreter Protocol.\r
+  //\r
+  mProtocolHandle = NULL;\r
+  Status = gBS->InstallProtocolInterface (\r
+                  &mProtocolHandle,\r
+                  &gEfiRestJsonStructureProtocolGuid,\r
+                  EFI_NATIVE_INTERFACE,\r
+                  (VOID *)&mRestJsonStructureProtocol\r
+                  );\r
+  return Status;\r
+}\r
+\r
+/**\r
+  This is the unload handle for Redfish discover module.\r
+\r
+  Disconnect the driver specified by ImageHandle from all the devices in the handle database.\r
+  Uninstall all the protocols installed in the driver entry point.\r
+\r
+  @param[in] ImageHandle           The drivers' driver image.\r
+\r
+  @retval    EFI_SUCCESS           The image is unloaded.\r
+  @retval    Others                Failed to unload the image.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+RestJsonStructureUnload (\r
+  IN EFI_HANDLE ImageHandle\r
+  )\r
+{\r
+  EFI_STATUS Status;\r
+  REST_JSON_STRUCTURE_INSTANCE *Instance;\r
+  REST_JSON_STRUCTURE_INSTANCE *NextInstance;\r
+\r
+  Status = gBS->UninstallProtocolInterface (\r
+                  mProtocolHandle,\r
+                  &gEfiRestJsonStructureProtocolGuid,\r
+                  (VOID *)&mRestJsonStructureProtocol\r
+                  );\r
+\r
+  if (IsListEmpty (&mRestJsonStructureList)) {\r
+    return Status;\r
+  }\r
+  //\r
+  // Free memory of REST_JSON_STRUCTURE_INSTANCE instance.\r
+  //\r
+  Instance = (REST_JSON_STRUCTURE_INSTANCE *)GetFirstNode (&mRestJsonStructureList);\r
+  do {\r
+    NextInstance = NULL;\r
+    if (!IsNodeAtEnd(&mRestJsonStructureList, &Instance->NextRestJsonStructureInstance)) {\r
+      NextInstance = (REST_JSON_STRUCTURE_INSTANCE *)GetNextNode (&mRestJsonStructureList, &Instance->NextRestJsonStructureInstance);\r
+    }\r
+    FreePool ((VOID *)Instance);\r
+    Instance = NextInstance;\r
+  } while (Instance != NULL);\r
+\r
+  return Status;\r
+}\r
diff --git a/RedfishPkg/RestJsonStructureDxe/RestJsonStructureDxe.inf b/RedfishPkg/RestJsonStructureDxe/RestJsonStructureDxe.inf
new file mode 100644 (file)
index 0000000..61e6253
--- /dev/null
@@ -0,0 +1,39 @@
+## @file\r
+# Implementation of EFI REST JSON Structure Protocol.\r
+#\r
+#  (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>\r
+#  SPDX-License-Identifier: BSD-2-Clause-Patent\r
+##\r
+\r
+[Defines]\r
+  INF_VERSION               = 0x00010005\r
+  BASE_NAME                 = RestJsonStructureDxe\r
+  FILE_GUID                 = 83FAAFBF-FC4B-469F-892A-798E66A6F50A\r
+  MODULE_TYPE               = DXE_DRIVER\r
+  VERSION_STRING            = 1.0\r
+  ENTRY_POINT               = RestJsonStructureEntryPoint\r
+  UNLOAD_IMAGE              = RestJsonStructureUnload\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+  MdeModulePkg/MdeModulePkg.dec\r
+  RedfishPkg/RedfishPkg.dec\r
+\r
+[Sources]\r
+  RestJsonStructureDxe.c\r
+  RestJsonStructureInternal.h\r
+\r
+[LibraryClasses]\r
+  BaseLib\r
+  BaseMemoryLib\r
+  MemoryAllocationLib\r
+  UefiBootServicesTableLib\r
+  UefiDriverEntryPoint\r
+  UefiLib\r
+\r
+[Protocols]\r
+  gEfiRestJsonStructureProtocolGuid    ## Producing\r
+\r
+[Depex]\r
+  TRUE\r
+\r
diff --git a/RedfishPkg/RestJsonStructureDxe/RestJsonStructureInternal.h b/RedfishPkg/RestJsonStructureDxe/RestJsonStructureInternal.h
new file mode 100644 (file)
index 0000000..e8a3408
--- /dev/null
@@ -0,0 +1,33 @@
+/** @file\r
+  The internal definitions of EFI REST Resource JSON to C structure convertor\r
+  Protocol.\r
+\r
+  (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>\r
+\r
+  SPDX-License-Identifier: BSD-2-Clause-Patent\r
+\r
+**/\r
+\r
+#ifndef EFI_REST_JSON_STRUCTURE_INTERNAL_H_\r
+#define EFI_REST_JSON_STRUCTURE_INTERNAL_H_\r
+\r
+#include <Library/BaseLib.h>\r
+#include <Library/UefiLib.h>\r
+#include <Library/UefiBootServicesTableLib.h>\r
+#include <Library/UefiDriverEntryPoint.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/MemoryAllocationLib.h>\r
+\r
+///\r
+/// Internal structure to maintain the information of JSON to\r
+/// C structure convertor.\r
+///\r
+typedef struct _REST_JSON_STRUCTURE_INSTANCE {\r
+  LIST_ENTRY NextRestJsonStructureInstance;  ///< Next convertor instance\r
+  UINTN NumberOfNameSpaceToConvert;          ///< Number of resource type this convertor supports.\r
+  EFI_REST_JSON_RESOURCE_TYPE_IDENTIFIER     *SupportedRsrcIndentifier; ///< The resource type linklist\r
+  EFI_REST_JSON_STRUCTURE_TO_STRUCTURE        JsonToStructure;          ///< JSON to C structure function\r
+  EFI_REST_JSON_STRUCTURE_TO_JSON             StructureToJson;          ///< C structure to JSON function\r
+  EFI_REST_JSON_STRUCTURE_DESTORY_STRUCTURE   DestroyStructure;         ///< Destory C struture function.\r
+} REST_JSON_STRUCTURE_INSTANCE;\r
+#endif\r