/** @file | |
The implementation of EFI REST Resource JSON to C structure convertor | |
Protocol. | |
(C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR> | |
Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR> | |
SPDX-License-Identifier: BSD-2-Clause-Patent | |
**/ | |
#include <Uefi.h> | |
#include <Library/DebugLib.h> | |
#include <Protocol/RestJsonStructure.h> | |
#include "RestJsonStructureInternal.h" | |
LIST_ENTRY mRestJsonStructureList; | |
EFI_HANDLE mProtocolHandle; | |
/** | |
This function registers Restful resource interpreter for the | |
specific schema. | |
@param[in] This This is the EFI_REST_JSON_STRUCTURE_PROTOCOL instance. | |
@param[in] JsonStructureSupported The type and version of REST JSON resource which this converter | |
supports. | |
@param[in] ToStructure The function to convert REST JSON resource to structure. | |
@param[in] ToJson The function to convert REST JSON structure to JSON in text format. | |
@param[in] DestroyStructure Destroy REST JSON structure returned in ToStructure() function. | |
@retval EFI_SUCCESS Register successfully. | |
@retval Others Fail to register. | |
**/ | |
EFI_STATUS | |
EFIAPI | |
RestJsonStructureRegister ( | |
IN EFI_REST_JSON_STRUCTURE_PROTOCOL *This, | |
IN EFI_REST_JSON_STRUCTURE_SUPPORTED *JsonStructureSupported, | |
IN EFI_REST_JSON_STRUCTURE_TO_STRUCTURE ToStructure, | |
IN EFI_REST_JSON_STRUCTURE_TO_JSON ToJson, | |
IN EFI_REST_JSON_STRUCTURE_DESTORY_STRUCTURE DestroyStructure | |
) | |
{ | |
UINTN NumberOfNS; | |
UINTN Index; | |
LIST_ENTRY *ThisList; | |
REST_JSON_STRUCTURE_INSTANCE *Instance; | |
EFI_REST_JSON_RESOURCE_TYPE_IDENTIFIER *CloneSupportedInterpId; | |
EFI_REST_JSON_STRUCTURE_SUPPORTED *ThisSupportedInterp; | |
if ((This == NULL) || | |
(ToStructure == NULL) || | |
(ToJson == NULL) || | |
(DestroyStructure == NULL) || | |
(JsonStructureSupported == NULL) | |
) | |
{ | |
return EFI_INVALID_PARAMETER; | |
} | |
// | |
// Check how many name space interpreter can interpret. | |
// | |
ThisList = &JsonStructureSupported->NextSupportedRsrcInterp; | |
NumberOfNS = 1; | |
while (TRUE) { | |
if (ThisList->ForwardLink == &JsonStructureSupported->NextSupportedRsrcInterp) { | |
break; | |
} else { | |
ThisList = ThisList->ForwardLink; | |
NumberOfNS++; | |
} | |
} | |
DEBUG ((DEBUG_MANAGEABILITY, "%a: %d REST JSON-C interpreter(s) to register for the name spaces.\n", __func__, NumberOfNS)); | |
Instance = | |
(REST_JSON_STRUCTURE_INSTANCE *)AllocateZeroPool (sizeof (REST_JSON_STRUCTURE_INSTANCE) + NumberOfNS * sizeof (EFI_REST_JSON_RESOURCE_TYPE_IDENTIFIER)); | |
if (Instance == NULL) { | |
return EFI_OUT_OF_RESOURCES; | |
} | |
InitializeListHead (&Instance->NextRestJsonStructureInstance); | |
Instance->NumberOfNameSpaceToConvert = NumberOfNS; | |
Instance->SupportedRsrcIndentifier = (EFI_REST_JSON_RESOURCE_TYPE_IDENTIFIER *)((REST_JSON_STRUCTURE_INSTANCE *)Instance + 1); | |
// | |
// Copy supported resource identifer interpreter. | |
// | |
CloneSupportedInterpId = Instance->SupportedRsrcIndentifier; | |
ThisSupportedInterp = JsonStructureSupported; | |
for (Index = 0; Index < NumberOfNS; Index++) { | |
CopyMem ((VOID *)CloneSupportedInterpId, (VOID *)&ThisSupportedInterp->RestResourceInterp, sizeof (EFI_REST_JSON_RESOURCE_TYPE_IDENTIFIER)); | |
DEBUG ((DEBUG_MANAGEABILITY, " Resource type : %a\n", ThisSupportedInterp->RestResourceInterp.NameSpace.ResourceTypeName)); | |
DEBUG ((DEBUG_MANAGEABILITY, " Major version : %a\n", ThisSupportedInterp->RestResourceInterp.NameSpace.MajorVersion)); | |
DEBUG ((DEBUG_MANAGEABILITY, " Minor version : %a\n", ThisSupportedInterp->RestResourceInterp.NameSpace.MinorVersion)); | |
DEBUG ((DEBUG_MANAGEABILITY, " Errata version: %a\n\n", ThisSupportedInterp->RestResourceInterp.NameSpace.ErrataVersion)); | |
ThisSupportedInterp = (EFI_REST_JSON_STRUCTURE_SUPPORTED *)ThisSupportedInterp->NextSupportedRsrcInterp.ForwardLink; | |
CloneSupportedInterpId++; | |
} | |
Instance->JsonToStructure = ToStructure; | |
Instance->StructureToJson = ToJson; | |
Instance->DestroyStructure = DestroyStructure; | |
InsertTailList (&mRestJsonStructureList, &Instance->NextRestJsonStructureInstance); | |
return EFI_SUCCESS; | |
} | |
/** | |
This function check if this interpreter instance support the given namesapce. | |
@param[in] This EFI_REST_JSON_STRUCTURE_PROTOCOL instance. | |
@param[in] InterpreterInstance REST_JSON_STRUCTURE_INSTANCE | |
@param[in] RsrcTypeIdentifier Resource type identifier. | |
@param[in] ResourceRaw Given Restful resource. | |
@param[out] RestJSonHeader Property interpreted from given ResourceRaw. | |
@retval EFI_SUCCESS | |
@retval Others. | |
**/ | |
EFI_STATUS | |
InterpreterInstanceToStruct ( | |
IN EFI_REST_JSON_STRUCTURE_PROTOCOL *This, | |
IN REST_JSON_STRUCTURE_INSTANCE *InterpreterInstance, | |
IN EFI_REST_JSON_RESOURCE_TYPE_IDENTIFIER *RsrcTypeIdentifier OPTIONAL, | |
IN CHAR8 *ResourceRaw, | |
OUT EFI_REST_JSON_STRUCTURE_HEADER **RestJSonHeader | |
) | |
{ | |
UINTN Index; | |
EFI_STATUS Status; | |
EFI_REST_JSON_RESOURCE_TYPE_IDENTIFIER *ThisSupportedRsrcTypeId; | |
DEBUG ((DEBUG_MANAGEABILITY, "%a: Entry\n", __func__)); | |
if ((This == NULL) || | |
(InterpreterInstance == NULL) || | |
(ResourceRaw == NULL) || | |
(RestJSonHeader == NULL) | |
) | |
{ | |
return EFI_INVALID_PARAMETER; | |
} | |
Status = EFI_UNSUPPORTED; | |
if (RsrcTypeIdentifier == NULL) { | |
// | |
// No resource type identifier, send to intepreter anyway. | |
// Interpreter may recognize this resource. | |
// | |
Status = InterpreterInstance->JsonToStructure ( | |
This, | |
NULL, | |
ResourceRaw, | |
RestJSonHeader | |
); | |
if (EFI_ERROR (Status)) { | |
if (Status == EFI_UNSUPPORTED) { | |
DEBUG (( | |
DEBUG_MANAGEABILITY, | |
"%a %a.%a.%a REST JSON to C structure interpreter has no capability to interpret the resource.\n", | |
InterpreterInstance->SupportedRsrcIndentifier->NameSpace.ResourceTypeName, | |
InterpreterInstance->SupportedRsrcIndentifier->NameSpace.MajorVersion, | |
InterpreterInstance->SupportedRsrcIndentifier->NameSpace.MinorVersion, | |
InterpreterInstance->SupportedRsrcIndentifier->NameSpace.ErrataVersion | |
)); | |
} else { | |
DEBUG ((DEBUG_MANAGEABILITY, "REST JsonToStructure returns failure - %r\n", Status)); | |
} | |
} | |
} else { | |
// | |
// Check if the namespace and version is supported by this interpreter. | |
// | |
ThisSupportedRsrcTypeId = InterpreterInstance->SupportedRsrcIndentifier; | |
for (Index = 0; Index < InterpreterInstance->NumberOfNameSpaceToConvert; Index++) { | |
if (AsciiStrCmp ( | |
RsrcTypeIdentifier->NameSpace.ResourceTypeName, | |
ThisSupportedRsrcTypeId->NameSpace.ResourceTypeName | |
) == 0) | |
{ | |
if ((RsrcTypeIdentifier->NameSpace.MajorVersion == NULL) && | |
(RsrcTypeIdentifier->NameSpace.MinorVersion == NULL) && | |
(RsrcTypeIdentifier->NameSpace.ErrataVersion == NULL) | |
) | |
{ | |
// | |
// Don't check version of this resource type identifier. | |
// | |
Status = InterpreterInstance->JsonToStructure ( | |
This, | |
RsrcTypeIdentifier, | |
ResourceRaw, | |
RestJSonHeader | |
); | |
if (EFI_ERROR (Status)) { | |
DEBUG ((DEBUG_MANAGEABILITY, "Don't check version of this resource type identifier JsonToStructure returns %r\n", Status)); | |
DEBUG ((DEBUG_MANAGEABILITY, " Supported ResourceTypeName = %a\n", ThisSupportedRsrcTypeId->NameSpace.ResourceTypeName)); | |
} | |
break; | |
} else { | |
// | |
// Check version. | |
// | |
if ((AsciiStrCmp ( | |
RsrcTypeIdentifier->NameSpace.MajorVersion, | |
ThisSupportedRsrcTypeId->NameSpace.MajorVersion | |
) == 0) && | |
(AsciiStrCmp ( | |
RsrcTypeIdentifier->NameSpace.MinorVersion, | |
ThisSupportedRsrcTypeId->NameSpace.MinorVersion | |
) == 0) && | |
(AsciiStrCmp ( | |
RsrcTypeIdentifier->NameSpace.ErrataVersion, | |
ThisSupportedRsrcTypeId->NameSpace.ErrataVersion | |
) == 0)) | |
{ | |
Status = InterpreterInstance->JsonToStructure ( | |
This, | |
RsrcTypeIdentifier, | |
ResourceRaw, | |
RestJSonHeader | |
); | |
if (EFI_ERROR (Status)) { | |
DEBUG ((DEBUG_MANAGEABILITY, "Check version of this resource type identifier JsonToStructure returns %r\n", Status)); | |
DEBUG ((DEBUG_MANAGEABILITY, " Supported ResourceTypeName = %a\n", ThisSupportedRsrcTypeId->NameSpace.ResourceTypeName)); | |
DEBUG ((DEBUG_MANAGEABILITY, " Supported MajorVersion = %a\n", ThisSupportedRsrcTypeId->NameSpace.MajorVersion)); | |
DEBUG ((DEBUG_MANAGEABILITY, " Supported MinorVersion = %a\n", ThisSupportedRsrcTypeId->NameSpace.MinorVersion)); | |
DEBUG ((DEBUG_MANAGEABILITY, " Supported ErrataVersion = %a\n", ThisSupportedRsrcTypeId->NameSpace.ErrataVersion)); | |
} | |
break; | |
} | |
} | |
} | |
ThisSupportedRsrcTypeId++; | |
} | |
} | |
return Status; | |
} | |
/** | |
This function converts JSON C structure to JSON property. | |
@param[in] This EFI_REST_JSON_STRUCTURE_PROTOCOL instance. | |
@param[in] InterpreterInstance REST_JSON_STRUCTURE_INSTANCE | |
@param[in] RestJSonHeader Resource type identifier. | |
@param[out] ResourceRaw Output in JSON text format. | |
@retval EFI_SUCCESS | |
@retval Others. | |
**/ | |
EFI_STATUS | |
InterpreterEfiStructToInstance ( | |
IN EFI_REST_JSON_STRUCTURE_PROTOCOL *This, | |
IN REST_JSON_STRUCTURE_INSTANCE *InterpreterInstance, | |
IN EFI_REST_JSON_STRUCTURE_HEADER *RestJSonHeader, | |
OUT CHAR8 **ResourceRaw | |
) | |
{ | |
UINTN Index; | |
EFI_STATUS Status; | |
EFI_REST_JSON_RESOURCE_TYPE_IDENTIFIER *ThisSupportedRsrcTypeId; | |
EFI_REST_JSON_RESOURCE_TYPE_IDENTIFIER *RsrcTypeIdentifier; | |
DEBUG ((DEBUG_MANAGEABILITY, "%a: Entry\n", __func__)); | |
if ((This == NULL) || | |
(InterpreterInstance == NULL) || | |
(RestJSonHeader == NULL) || | |
(ResourceRaw == NULL) | |
) | |
{ | |
return EFI_INVALID_PARAMETER; | |
} | |
RsrcTypeIdentifier = &RestJSonHeader->JsonRsrcIdentifier; | |
if ((RsrcTypeIdentifier == NULL) || | |
(RsrcTypeIdentifier->NameSpace.ResourceTypeName == NULL) || | |
(RsrcTypeIdentifier->NameSpace.MajorVersion == NULL) || | |
(RsrcTypeIdentifier->NameSpace.MinorVersion == NULL) || | |
(RsrcTypeIdentifier->NameSpace.ErrataVersion == NULL) | |
) | |
{ | |
return EFI_INVALID_PARAMETER; | |
} | |
// | |
// Check if the namesapce and version is supported by this interpreter. | |
// | |
Status = EFI_UNSUPPORTED; | |
ThisSupportedRsrcTypeId = InterpreterInstance->SupportedRsrcIndentifier; | |
for (Index = 0; Index < InterpreterInstance->NumberOfNameSpaceToConvert; Index++) { | |
if (AsciiStrCmp ( | |
RsrcTypeIdentifier->NameSpace.ResourceTypeName, | |
ThisSupportedRsrcTypeId->NameSpace.ResourceTypeName | |
) == 0) | |
{ | |
// | |
// Check version. | |
// | |
if ((AsciiStrCmp ( | |
RsrcTypeIdentifier->NameSpace.MajorVersion, | |
ThisSupportedRsrcTypeId->NameSpace.MajorVersion | |
) == 0) && | |
(AsciiStrCmp ( | |
RsrcTypeIdentifier->NameSpace.MinorVersion, | |
ThisSupportedRsrcTypeId->NameSpace.MinorVersion | |
) == 0) && | |
(AsciiStrCmp ( | |
RsrcTypeIdentifier->NameSpace.ErrataVersion, | |
ThisSupportedRsrcTypeId->NameSpace.ErrataVersion | |
) == 0)) | |
{ | |
Status = InterpreterInstance->StructureToJson ( | |
This, | |
RestJSonHeader, | |
ResourceRaw | |
); | |
if (EFI_ERROR (Status)) { | |
DEBUG ((DEBUG_MANAGEABILITY, "StructureToJson returns %r\n", Status)); | |
DEBUG ((DEBUG_MANAGEABILITY, " Supported ResourceTypeName = %a\n", ThisSupportedRsrcTypeId->NameSpace.ResourceTypeName)); | |
DEBUG ((DEBUG_MANAGEABILITY, " Supported MajorVersion = %a\n", ThisSupportedRsrcTypeId->NameSpace.MajorVersion)); | |
DEBUG ((DEBUG_MANAGEABILITY, " Supported MinorVersion = %a\n", ThisSupportedRsrcTypeId->NameSpace.MinorVersion)); | |
DEBUG ((DEBUG_MANAGEABILITY, " Supported ErrataVersion = %a\n", ThisSupportedRsrcTypeId->NameSpace.ErrataVersion)); | |
} | |
break; | |
} | |
} | |
ThisSupportedRsrcTypeId++; | |
} | |
return Status; | |
} | |
/** | |
This function destory REST property structure. | |
@param[in] This EFI_REST_JSON_STRUCTURE_PROTOCOL instance. | |
@param[in] InterpreterInstance REST_JSON_STRUCTURE_INSTANCE | |
@param[in] RestJSonHeader Property interpreted from given ResourceRaw. | |
@retval EFI_SUCCESS | |
@retval Others. | |
**/ | |
EFI_STATUS | |
InterpreterInstanceDestoryJsonStruct ( | |
IN EFI_REST_JSON_STRUCTURE_PROTOCOL *This, | |
IN REST_JSON_STRUCTURE_INSTANCE *InterpreterInstance, | |
IN EFI_REST_JSON_STRUCTURE_HEADER *RestJSonHeader | |
) | |
{ | |
UINTN Index; | |
EFI_STATUS Status; | |
EFI_REST_JSON_RESOURCE_TYPE_IDENTIFIER *ThisSupportedRsrcTypeId; | |
if ((This == NULL) || | |
(InterpreterInstance == NULL) || | |
(RestJSonHeader == NULL) | |
) | |
{ | |
return EFI_INVALID_PARAMETER; | |
} | |
Status = EFI_UNSUPPORTED; | |
// | |
// Check if the namesapce and version is supported by this interpreter. | |
// | |
ThisSupportedRsrcTypeId = InterpreterInstance->SupportedRsrcIndentifier; | |
for (Index = 0; Index < InterpreterInstance->NumberOfNameSpaceToConvert; Index++) { | |
if (AsciiStrCmp ( | |
RestJSonHeader->JsonRsrcIdentifier.NameSpace.ResourceTypeName, | |
ThisSupportedRsrcTypeId->NameSpace.ResourceTypeName | |
) == 0) | |
{ | |
if ((RestJSonHeader->JsonRsrcIdentifier.NameSpace.MajorVersion == NULL) && | |
(RestJSonHeader->JsonRsrcIdentifier.NameSpace.MinorVersion == NULL) && | |
(RestJSonHeader->JsonRsrcIdentifier.NameSpace.ErrataVersion == NULL) | |
) | |
{ | |
// | |
// Don't check version of this resource type identifier. | |
// | |
Status = InterpreterInstance->DestroyStructure ( | |
This, | |
RestJSonHeader | |
); | |
break; | |
} else { | |
// | |
// Check version. | |
// | |
if ((AsciiStrCmp ( | |
RestJSonHeader->JsonRsrcIdentifier.NameSpace.MajorVersion, | |
ThisSupportedRsrcTypeId->NameSpace.MajorVersion | |
) == 0) && | |
(AsciiStrCmp ( | |
RestJSonHeader->JsonRsrcIdentifier.NameSpace.MinorVersion, | |
ThisSupportedRsrcTypeId->NameSpace.MinorVersion | |
) == 0) && | |
(AsciiStrCmp ( | |
RestJSonHeader->JsonRsrcIdentifier.NameSpace.ErrataVersion, | |
ThisSupportedRsrcTypeId->NameSpace.ErrataVersion | |
) == 0)) | |
{ | |
Status = InterpreterInstance->DestroyStructure ( | |
This, | |
RestJSonHeader | |
); | |
break; | |
} | |
} | |
} | |
ThisSupportedRsrcTypeId++; | |
} | |
return Status; | |
} | |
/** | |
This function translates the given JSON text to JSON C Structure. | |
@param[in] This EFI_REST_JSON_STRUCTURE_PROTOCOL instance. | |
@param[in] RsrcTypeIdentifier Resource type identifier. | |
@param[in] ResourceJsonText Given Restful resource. | |
@param[out] JsonStructure Property interpreted from given ResourceRaw. | |
@retval EFI_SUCCESS | |
@retval Others. | |
**/ | |
EFI_STATUS | |
EFIAPI | |
RestJsonStructureToStruct ( | |
IN EFI_REST_JSON_STRUCTURE_PROTOCOL *This, | |
IN EFI_REST_JSON_RESOURCE_TYPE_IDENTIFIER *RsrcTypeIdentifier OPTIONAL, | |
IN CHAR8 *ResourceJsonText, | |
OUT EFI_REST_JSON_STRUCTURE_HEADER **JsonStructure | |
) | |
{ | |
EFI_STATUS Status; | |
REST_JSON_STRUCTURE_INSTANCE *Instance; | |
if ((This == NULL) || | |
(ResourceJsonText == NULL) || | |
(JsonStructure == NULL) | |
) | |
{ | |
return EFI_INVALID_PARAMETER; | |
} | |
if (IsListEmpty (&mRestJsonStructureList)) { | |
return EFI_UNSUPPORTED; | |
} | |
if (RsrcTypeIdentifier != NULL) { | |
DEBUG ((DEBUG_MANAGEABILITY, "%a: Looking for the REST JSON to C Structure converter:\n", __func__)); | |
if (RsrcTypeIdentifier->NameSpace.ResourceTypeName != NULL) { | |
DEBUG ((DEBUG_MANAGEABILITY, " ResourceType: %a\n", RsrcTypeIdentifier->NameSpace.ResourceTypeName)); | |
} else { | |
DEBUG ((DEBUG_MANAGEABILITY, " ResourceType: NULL")); | |
} | |
if (RsrcTypeIdentifier->NameSpace.MajorVersion != NULL) { | |
DEBUG ((DEBUG_MANAGEABILITY, " MajorVersion: %a\n", RsrcTypeIdentifier->NameSpace.MajorVersion)); | |
} else { | |
DEBUG ((DEBUG_MANAGEABILITY, " MajorVersion: NULL")); | |
} | |
if (RsrcTypeIdentifier->NameSpace.MinorVersion != NULL) { | |
DEBUG ((DEBUG_MANAGEABILITY, " MinorVersion: %a\n", RsrcTypeIdentifier->NameSpace.MinorVersion)); | |
} else { | |
DEBUG ((DEBUG_MANAGEABILITY, " MinorVersion: NULL")); | |
} | |
if (RsrcTypeIdentifier->NameSpace.ErrataVersion != NULL) { | |
DEBUG ((DEBUG_MANAGEABILITY, " ErrataVersion: %a\n", RsrcTypeIdentifier->NameSpace.ErrataVersion)); | |
} else { | |
DEBUG ((DEBUG_MANAGEABILITY, " ErrataVersion: NULL")); | |
} | |
} else { | |
DEBUG ((DEBUG_MANAGEABILITY, "%a: RsrcTypeIdentifier is given as NULL, go through all of the REST JSON to C structure interpreters.\n", __func__)); | |
} | |
Status = EFI_SUCCESS; | |
Instance = (REST_JSON_STRUCTURE_INSTANCE *)GetFirstNode (&mRestJsonStructureList); | |
while (TRUE) { | |
Status = InterpreterInstanceToStruct ( | |
This, | |
Instance, | |
RsrcTypeIdentifier, | |
ResourceJsonText, | |
JsonStructure | |
); | |
if (!EFI_ERROR (Status)) { | |
DEBUG ((DEBUG_MANAGEABILITY, "%a: REST JSON to C structure is interpreted successfully.\n", __func__)); | |
break; | |
} | |
if (IsNodeAtEnd (&mRestJsonStructureList, &Instance->NextRestJsonStructureInstance)) { | |
DEBUG ((DEBUG_ERROR, "%a: No REST JSON to C structure interpreter found.\n", __func__)); | |
Status = EFI_UNSUPPORTED; | |
break; | |
} | |
Instance = (REST_JSON_STRUCTURE_INSTANCE *)GetNextNode (&mRestJsonStructureList, &Instance->NextRestJsonStructureInstance); | |
} | |
return Status; | |
} | |
/** | |
This function destory REST property EFI structure which returned in | |
JsonToStructure(). | |
@param[in] This EFI_REST_JSON_STRUCTURE_PROTOCOL instance. | |
@param[in] RestJSonHeader Property to destory. | |
@retval EFI_SUCCESS | |
@retval Others | |
**/ | |
EFI_STATUS | |
EFIAPI | |
RestJsonStructureDestroyStruct ( | |
IN EFI_REST_JSON_STRUCTURE_PROTOCOL *This, | |
IN EFI_REST_JSON_STRUCTURE_HEADER *RestJSonHeader | |
) | |
{ | |
EFI_STATUS Status; | |
REST_JSON_STRUCTURE_INSTANCE *Instance; | |
if ((This == NULL) || (RestJSonHeader == NULL)) { | |
return EFI_INVALID_PARAMETER; | |
} | |
if (IsListEmpty (&mRestJsonStructureList)) { | |
return EFI_UNSUPPORTED; | |
} | |
Status = EFI_SUCCESS; | |
Instance = (REST_JSON_STRUCTURE_INSTANCE *)GetFirstNode (&mRestJsonStructureList); | |
while (TRUE) { | |
Status = InterpreterInstanceDestoryJsonStruct ( | |
This, | |
Instance, | |
RestJSonHeader | |
); | |
if (!EFI_ERROR (Status)) { | |
break; | |
} | |
if (IsNodeAtEnd (&mRestJsonStructureList, &Instance->NextRestJsonStructureInstance)) { | |
DEBUG ((DEBUG_ERROR, "%a: No REST JSON to C structure interpreter found.\n", __func__)); | |
Status = EFI_UNSUPPORTED; | |
break; | |
} | |
Instance = (REST_JSON_STRUCTURE_INSTANCE *)GetNextNode (&mRestJsonStructureList, &Instance->NextRestJsonStructureInstance); | |
} | |
return Status; | |
} | |
/** | |
This function translates the given JSON C Structure to JSON text. | |
@param[in] This EFI_REST_JSON_STRUCTURE_PROTOCOL instance. | |
@param[in] RestJSonHeader Given Restful resource. | |
@param[out] ResourceRaw Resource in RESTfuls service oriented. | |
@retval EFI_SUCCESS | |
@retval Others Fail to remove the entry | |
**/ | |
EFI_STATUS | |
EFIAPI | |
RestJsonStructureToJson ( | |
IN EFI_REST_JSON_STRUCTURE_PROTOCOL *This, | |
IN EFI_REST_JSON_STRUCTURE_HEADER *RestJSonHeader, | |
OUT CHAR8 **ResourceRaw | |
) | |
{ | |
EFI_STATUS Status; | |
REST_JSON_STRUCTURE_INSTANCE *Instance; | |
EFI_REST_JSON_RESOURCE_TYPE_IDENTIFIER *RsrcTypeIdentifier; | |
if ((This == NULL) || (RestJSonHeader == NULL) || (ResourceRaw == NULL)) { | |
return EFI_INVALID_PARAMETER; | |
} | |
if (IsListEmpty (&mRestJsonStructureList)) { | |
return EFI_UNSUPPORTED; | |
} | |
RsrcTypeIdentifier = &RestJSonHeader->JsonRsrcIdentifier; | |
DEBUG ((DEBUG_MANAGEABILITY, "Looking for the REST C Structure to JSON resource converter:\n")); | |
DEBUG ((DEBUG_MANAGEABILITY, " ResourceType : %a\n", RsrcTypeIdentifier->NameSpace.ResourceTypeName)); | |
DEBUG ((DEBUG_MANAGEABILITY, " MajorVersion : %a\n", RsrcTypeIdentifier->NameSpace.MajorVersion)); | |
DEBUG ((DEBUG_MANAGEABILITY, " MinorVersion : %a\n", RsrcTypeIdentifier->NameSpace.MinorVersion)); | |
DEBUG ((DEBUG_MANAGEABILITY, " ErrataVersion: %a\n", RsrcTypeIdentifier->NameSpace.ErrataVersion)); | |
Status = EFI_SUCCESS; | |
Instance = (REST_JSON_STRUCTURE_INSTANCE *)GetFirstNode (&mRestJsonStructureList); | |
while (TRUE) { | |
Status = InterpreterEfiStructToInstance ( | |
This, | |
Instance, | |
RestJSonHeader, | |
ResourceRaw | |
); | |
if (!EFI_ERROR (Status)) { | |
break; | |
} | |
if (IsNodeAtEnd (&mRestJsonStructureList, &Instance->NextRestJsonStructureInstance)) { | |
DEBUG ((DEBUG_ERROR, "%a: No REST C structure to JSON interpreter found.\n", __func__)); | |
Status = EFI_UNSUPPORTED; | |
break; | |
} | |
Instance = (REST_JSON_STRUCTURE_INSTANCE *)GetNextNode (&mRestJsonStructureList, &Instance->NextRestJsonStructureInstance); | |
} | |
return Status; | |
} | |
EFI_REST_JSON_STRUCTURE_PROTOCOL mRestJsonStructureProtocol = { | |
RestJsonStructureRegister, | |
RestJsonStructureToStruct, | |
RestJsonStructureToJson, | |
RestJsonStructureDestroyStruct | |
}; | |
/** | |
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 | |
RestJsonStructureEntryPoint ( | |
IN EFI_HANDLE ImageHandle, | |
IN EFI_SYSTEM_TABLE *SystemTable | |
) | |
{ | |
EFI_STATUS Status; | |
InitializeListHead (&mRestJsonStructureList); | |
// | |
// Install the Restful Resource Interpreter Protocol. | |
// | |
mProtocolHandle = NULL; | |
Status = gBS->InstallProtocolInterface ( | |
&mProtocolHandle, | |
&gEfiRestJsonStructureProtocolGuid, | |
EFI_NATIVE_INTERFACE, | |
(VOID *)&mRestJsonStructureProtocol | |
); | |
return Status; | |
} | |
/** | |
This is the unload handle for REST JSON to C structure 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 | |
RestJsonStructureUnload ( | |
IN EFI_HANDLE ImageHandle | |
) | |
{ | |
EFI_STATUS Status; | |
REST_JSON_STRUCTURE_INSTANCE *Instance; | |
REST_JSON_STRUCTURE_INSTANCE *NextInstance; | |
Status = gBS->UninstallProtocolInterface ( | |
mProtocolHandle, | |
&gEfiRestJsonStructureProtocolGuid, | |
(VOID *)&mRestJsonStructureProtocol | |
); | |
if (IsListEmpty (&mRestJsonStructureList)) { | |
return Status; | |
} | |
// | |
// Free memory of REST_JSON_STRUCTURE_INSTANCE instance. | |
// | |
Instance = (REST_JSON_STRUCTURE_INSTANCE *)GetFirstNode (&mRestJsonStructureList); | |
do { | |
NextInstance = NULL; | |
if (!IsNodeAtEnd (&mRestJsonStructureList, &Instance->NextRestJsonStructureInstance)) { | |
NextInstance = (REST_JSON_STRUCTURE_INSTANCE *)GetNextNode (&mRestJsonStructureList, &Instance->NextRestJsonStructureInstance); | |
} | |
FreePool ((VOID *)Instance); | |
Instance = NextInstance; | |
} while (Instance != NULL); | |
return Status; | |
} |