From: "Chang, Abner" <abner.chang@amd.com>
To: Nickle Wang <nicklew@nvidia.com>,
"devel@edk2.groups.io" <devel@edk2.groups.io>
Cc: Igor Kulchytskyy <igork@ami.com>
Subject: Re: [edk2-redfish-client][PATCH 6/8] RedfishClientPkg: Add Redfish Feature Utility library
Date: Fri, 5 May 2023 01:15:20 +0000 [thread overview]
Message-ID: <MN2PR12MB3966ABBADC4F5F2E23B09A1CEA729@MN2PR12MB3966.namprd12.prod.outlook.com> (raw)
In-Reply-To: <20230504142540.17996-1-nicklew@nvidia.com>
[AMD Official Use Only - General]
Reviewed-by: Abner Chang <abner.chang@amd.com>
> -----Original Message-----
> From: Nickle Wang <nicklew@nvidia.com>
> Sent: Thursday, May 4, 2023 10:26 PM
> To: devel@edk2.groups.io
> Cc: Chang, Abner <Abner.Chang@amd.com>; Igor Kulchytskyy
> <igork@ami.com>
> Subject: [edk2-redfish-client][PATCH 6/8] RedfishClientPkg: Add Redfish
> Feature Utility library
>
> Caution: This message originated from an External Source. Use proper
> caution when opening attachments, clicking links, or responding.
>
>
> This is the helper library for EDKII Redfish feature drivers to
> manipulate Redfish properties.
>
> Signed-off-by: Nickle Wang <nicklew@nvidia.com>
> Cc: Abner Chang <abner.chang@amd.com>
> Cc: Igor Kulchytskyy <igork@ami.com>
> ---
> RedfishClientPkg/RedfishClientPkg.dec | 3 +
> RedfishClientPkg/RedfishClientLibs.dsc.inc | 3 +
> RedfishClientPkg/RedfishClientPkg.dsc | 2 +
> .../RedfishFeatureUtilityLib.inf | 50 +
> .../Library/RedfishFeatureUtilityLib.h | 471 +++++
> .../RedfishFeatureUtilityInternal.h | 45 +
> .../RedfishFeatureUtilityLib.c | 1513 +++++++++++++++++
> 7 files changed, 2087 insertions(+)
> create mode 100644
> RedfishClientPkg/Library/RedfishFeatureUtilityLib/RedfishFeatureUtilityLib.i
> nf
> create mode 100644
> RedfishClientPkg/Include/Library/RedfishFeatureUtilityLib.h
> create mode 100644
> RedfishClientPkg/Library/RedfishFeatureUtilityLib/RedfishFeatureUtilityInter
> nal.h
> create mode 100644
> RedfishClientPkg/Library/RedfishFeatureUtilityLib/RedfishFeatureUtilityLib.c
>
> diff --git a/RedfishClientPkg/RedfishClientPkg.dec
> b/RedfishClientPkg/RedfishClientPkg.dec
> index f0fe3269..b965f915 100644
> --- a/RedfishClientPkg/RedfishClientPkg.dec
> +++ b/RedfishClientPkg/RedfishClientPkg.dec
> @@ -19,6 +19,9 @@
> PrivateInclude # Private header files
> PrivateInclude/Crt # Private header files for C RTL.
>
> +[LibraryClasses]
> + RedfishFeatureUtilityLib|Include/Library/RedfishFeatureUtilityLib.h
> +
> [Protocols]
> ## Include/Protocol/EdkIIRedfishFeature.h
> gEdkIIRedfishFeatureProtocolGuid = { 0x785CC694, 0x4930, 0xEFBF,
> { 0x2A, 0xCB, 0xA4, 0xB6, 0xA1, 0xCC, 0xAA, 0x34 } }
> diff --git a/RedfishClientPkg/RedfishClientLibs.dsc.inc
> b/RedfishClientPkg/RedfishClientLibs.dsc.inc
> index 7e313ae5..a5ae73ca 100644
> --- a/RedfishClientPkg/RedfishClientLibs.dsc.inc
> +++ b/RedfishClientPkg/RedfishClientLibs.dsc.inc
> @@ -14,3 +14,6 @@
> !include RedfishClientPkg/RedfishJsonStructureLib.dsc.inc
> !endif
>
> +
> RedfishFeatureUtilityLib|RedfishClientPkg/Library/RedfishFeatureUtilityLib/
> RedfishFeatureUtilityLib.inf
> +
> RedfishPlatformConfigLib|RedfishPkg/Library/RedfishPlatformConfigLib/Red
> fishPlatformConfigLib.inf
> +
> diff --git a/RedfishClientPkg/RedfishClientPkg.dsc
> b/RedfishClientPkg/RedfishClientPkg.dsc
> index adb50cec..00a963ea 100644
> --- a/RedfishClientPkg/RedfishClientPkg.dsc
> +++ b/RedfishClientPkg/RedfishClientPkg.dsc
> @@ -47,4 +47,6 @@
>
> [Components]
>
> +
> RedfishClientPkg/Library/RedfishFeatureUtilityLib/RedfishFeatureUtilityLib.i
> nf
> +
> !include RedfishClientPkg/RedfishClient.dsc.inc
> diff --git
> a/RedfishClientPkg/Library/RedfishFeatureUtilityLib/RedfishFeatureUtilityLib
> .inf
> b/RedfishClientPkg/Library/RedfishFeatureUtilityLib/RedfishFeatureUtilityLib
> .inf
> new file mode 100644
> index 00000000..f9f283fd
> --- /dev/null
> +++
> b/RedfishClientPkg/Library/RedfishFeatureUtilityLib/RedfishFeatureUtilityLib
> .inf
> @@ -0,0 +1,50 @@
> +## @file
> +#
> +# (C) Copyright 2020-2021 Hewlett Packard Enterprise Development
> LP<BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> + INF_VERSION = 0x00010006
> + BASE_NAME = RedfishFeatureUtilityLib
> + FILE_GUID = 8BBE1212-A4BF-4ECA-B89B-8F85F83CC9B7
> + MODULE_TYPE = DXE_DRIVER
> + VERSION_STRING = 1.0
> + LIBRARY_CLASS = RedfishFeatureUtilityLib| DXE_DRIVER
> DXE_RUNTIME_DRIVER UEFI_APPLICATION UEFI_DRIVER
> + CONSTRUCTOR = RedfishFeatureUtilityLibConstructor
> + DESTRUCTOR = RedfishFeatureUtilityLibDestructor
> +
> +#
> +# VALID_ARCHITECTURES = IA32 X64 EBC
> +#
> +
> +[Sources]
> + RedfishFeatureUtilityLib.c
> + RedfishFeatureUtilityInternal.h
> +
> +[Packages]
> + MdePkg/MdePkg.dec
> + MdeModulePkg/MdeModulePkg.dec
> + RedfishPkg/RedfishPkg.dec
> + RedfishClientPkg/RedfishClientPkg.dec
> +
> +[LibraryClasses]
> + BaseLib
> + BaseMemoryLib
> + DebugLib
> + MemoryAllocationLib
> + PrintLib
> + RedfishLib
> + RedfishPlatformConfigLib
> + UefiLib
> + UefiBootServicesTableLib
> + UefiRuntimeServicesTableLib
> +
> +[Protocols]
> + gEdkIIRedfishETagProtocolGuid ## CONSUMED ##
> +
> +[Pcd]
> + gEfiRedfishClientPkgTokenSpaceGuid.PcdMaxRedfishSchemaStringSize
> + gEfiRedfishClientPkgTokenSpaceGuid.PcdMaxRedfishSchemaVersionSize
> diff --git a/RedfishClientPkg/Include/Library/RedfishFeatureUtilityLib.h
> b/RedfishClientPkg/Include/Library/RedfishFeatureUtilityLib.h
> new file mode 100644
> index 00000000..928fa4e8
> --- /dev/null
> +++ b/RedfishClientPkg/Include/Library/RedfishFeatureUtilityLib.h
> @@ -0,0 +1,471 @@
> +/** @file
> + This file defines the Redfish Feature Utility Library interface.
> +
> + (C) Copyright 2021 Hewlett Packard Enterprise Development LP<BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef REDFISH_FEATURE_UTILITY_LIB_H_
> +#define REDFISH_FEATURE_UTILITY_LIB_H_
> +
> +#include <Protocol/EdkIIRedfishResourceConfigProtocol.h>
> +#include <Protocol/RestJsonStructure.h>
> +
> +//
> +// Definition of REDFISH_FEATURE_ARRAY_TYPE_CONFIG_LANG
> +//
> +typedef struct {
> + UINTN Index;
> + EFI_STRING ConfigureLang;
> +} REDFISH_FEATURE_ARRAY_TYPE_CONFIG_LANG;
> +
> +//
> +// Definition of REDFISH_FEATURE_ARRAY_TYPE_CONFIG_LANG_LIST
> +//
> +typedef struct {
> + UINTN Count;
> + REDFISH_FEATURE_ARRAY_TYPE_CONFIG_LANG *List;
> +} REDFISH_FEATURE_ARRAY_TYPE_CONFIG_LANG_LIST;
> +
> +/**
> +
> + Read redfish resource by given resource path.
> +
> + @param[in] Service Redfish srvice instacne to make query.
> + @param[in] ResourcePath Target resource path.
> + @param[out] Response HTTP response from redfish service.
> +
> + @retval EFI_SUCCESS Resrouce is returned successfully.
> + @retval Others Errors occur.
> +
> +**/
> +EFI_STATUS
> +GetResourceByPath (
> + IN REDFISH_SERVICE *Service,
> + IN CHAR8 *ResourcePath,
> + OUT REDFISH_RESPONSE *Response
> + );
> +
> +/**
> +
> + Search HII database with given Configure Language pattern. Data is
> handled and
> + returned in array.
> +
> + @param[in] Schema The schema to search.
> + @param[in] Version The schema version.
> + @param[in] Pattern Configure Language pattern to search.
> + @param[out] UnifiedConfigureLangList The data returned by HII database.
> +
> + @retval EFI_SUCCESS Data is found and returned.
> + @retval Others Errors occur.
> +
> +**/
> +EFI_STATUS
> +RedfishFeatureGetUnifiedArrayTypeConfigureLang (
> + IN CHAR8 *Schema,
> + IN CHAR8 *Version,
> + IN EFI_STRING Pattern,
> + OUT REDFISH_FEATURE_ARRAY_TYPE_CONFIG_LANG_LIST
> *UnifiedConfigureLangList
> + );
> +
> +/**
> +
> + Get array key by parsing the URI.
> +
> + @param[in] Uri URI with array key.
> + @param[out] ArrayKey Array key in given URI string.
> +
> + @retval EFI_SUCCESS Array key is found.
> + @retval Others Errors occur.
> +
> +**/
> +EFI_STATUS
> +GetArraykeyFromUri (
> + IN CHAR8 *Uri,
> + OUT CHAR8 **ArrayKey
> + );
> +
> +/**
> +
> + Keep configure language with given key in UEFI variable.
> +
> + @param[in] Schema Schema name.
> + @param[in] Version Schema version.
> + @param[in] Key Key string.
> + @param[in] ConfigureLangIndex Index value.
> +
> + @retval EFI_SUCCESS Data is saved in UEFI variable.
> + @retval Others Errors occur.
> +
> +**/
> +EFI_STATUS
> +SetConfigureLangWithkey (
> + IN CHAR8 *Schema,
> + IN CHAR8 *Version,
> + IN CHAR8 *Key,
> + IN UINTN ConfigureLangIndex
> + );
> +
> +/**
> +
> + Find configure language with input key string.
> +
> + @param[in] Schema Schema name.
> + @param[in] Version Schema version.
> + @param[in] Property Property name.
> + @param[in] Key Key string.
> +
> + @retval CHAR16 * Corresponding configure langauge
> + @retval NULL No configure language is found
> +
> +**/
> +CHAR16 *
> +GetConfigureLangByKey (
> + IN CHAR8 *Schema,
> + IN CHAR8 *Version,
> + IN CHAR8 *Property,
> + IN CHAR8 *Key
> + );
> +
> +/**
> +
> + Convert HII string value to string value in JSON format.
> +
> + @param[in] HiiStringValue String in HII format.
> +
> + @retval CHAR8 * String in JSON format.
> + @retval NULL Errors occur.
> +
> +**/
> +CHAR8 *
> +ConvertHiiStringValueToJsonStringValue (
> + IN EFI_STRING HiiStringValue
> + );
> +
> +/**
> +
> + Apply property value to UEFI HII database in string type.
> +
> + @param[in] Schema Property schema.
> + @param[in] Version Property schema version.
> + @param[in] ConfigureLang Configure language refers to this property.
> + @param[in] FeatureValue New value to set.
> +
> + @retval EFI_SUCCESS New value is applied successfully.
> + @retval Others Errors occur.
> +
> +**/
> +EFI_STATUS
> +ApplyFeatureSettingsStringType (
> + IN CHAR8 *Schema,
> + IN CHAR8 *Version,
> + IN EFI_STRING ConfigureLang,
> + IN CHAR8 *FeatureValue
> + );
> +
> +/**
> +
> + Apply property value to UEFI HII database in numric type.
> +
> + @param[in] Schema Property schema.
> + @param[in] Version Property schema version.
> + @param[in] ConfigureLang Configure language refers to this property.
> + @param[in] FeatureValue New value to set.
> +
> + @retval EFI_SUCCESS New value is applied successfully.
> + @retval Others Errors occur.
> +
> +**/
> +EFI_STATUS
> +ApplyFeatureSettingsNumericType (
> + IN CHAR8 *Schema,
> + IN CHAR8 *Version,
> + IN EFI_STRING ConfigureLang,
> + IN INTN FeatureValue
> + );
> +
> +/**
> +
> + Apply property value to UEFI HII database in boolean type.
> +
> + @param[in] Schema Property schema.
> + @param[in] Version Property schema version.
> + @param[in] ConfigureLang Configure language refers to this property.
> + @param[in] FeatureValue New value to set.
> +
> + @retval EFI_SUCCESS New value is applied successfully.
> + @retval Others Errors occur.
> +
> +**/
> +EFI_STATUS
> +ApplyFeatureSettingsBooleanType (
> + IN CHAR8 *Schema,
> + IN CHAR8 *Version,
> + IN EFI_STRING ConfigureLang,
> + IN BOOLEAN FeatureValue
> + );
> +
> +/**
> +
> + Create HTTP payload and send them to redfish service with POST method.
> +
> + @param[in] Service Redfish service.
> + @param[in] TargetPayload Target payload
> + @param[in] Json Data in JSON format.
> + @param[out] Location Returned location string from Redfish service.
> + @param[out] Etag Returned ETAG string from Redfish service.
> +
> + @retval EFI_SUCCESS Data is sent to redfish service successfully.
> + @retval Others Errors occur.
> +
> +**/
> +EFI_STATUS
> +CreatePayloadToPostResource (
> + IN REDFISH_SERVICE *Service,
> + IN REDFISH_PAYLOAD *TargetPayload,
> + IN CHAR8 *Json,
> + OUT CHAR8 **Location,
> + OUT CHAR8 **Etag
> + );
> +
> +/**
> +
> + Create HTTP payload and send them to redfish service with PATCH method.
> +
> + @param[in] Service Redfish service.
> + @param[in] TargetPayload Target payload
> + @param[in] Json Data in JSON format.
> + @param[out] Etag Returned ETAG string from Redfish service.
> +
> + @retval EFI_SUCCESS Data is sent to redfish service successfully.
> + @retval Others Errors occur.
> +
> +**/
> +EFI_STATUS
> +CreatePayloadToPatchResource (
> + IN REDFISH_SERVICE *Service,
> + IN REDFISH_PAYLOAD *TargetPayload,
> + IN CHAR8 *Json,
> + OUT CHAR8 **Etag
> + );
> +
> +/**
> +
> + Find Redfish Resource Config Protocol that supports given schema and
> version.
> +
> + @param[in] Schema Schema name.
> + @param[in] Major Schema version major number.
> + @param[in] Minor Schema version minor number.
> + @param[in] Errata Schema version errata number.
> +
> + @retval EDKII_REDFISH_RESOURCE_CONFIG_PROTOCOL * Pointer to
> protocol
> + @retval NULL No protocol found.
> +
> +**/
> +EDKII_REDFISH_RESOURCE_CONFIG_PROTOCOL *
> +GetRedfishResourceConfigProtocol (
> + IN CHAR8 *Schema,
> + IN CHAR8 *Major,
> + IN CHAR8 *Minor,
> + IN CHAR8 *Errata
> + );
> +
> +/**
> +
> + Get supported schema list by given specify schema name.
> +
> + @param[in] Schema Schema type name.
> + @param[out] SchemaInfo Returned schema information.
> +
> + @retval EFI_SUCCESS Schema information is returned successfully.
> + @retval Others Errors occur.
> +
> +**/
> +EFI_STATUS
> +GetSupportedSchemaVersion (
> + IN CHAR8 *Schema,
> + OUT REDFISH_SCHEMA_INFO *SchemaInfo
> + );
> +
> +/**
> +
> + Return system root path
> +
> + @retval NULL Can not find system root path.
> + @retval Other System root path is returned.
> +
> +**/
> +CHAR8 *
> +RedfishGetSystemRootPath (
> + VOID
> + );
> +
> +/**
> +
> + Get schema information by given protocol and service instance.
> +
> + @param[in] RedfishService Pointer to Redfish service instance.
> + @param[in] JsonStructProtocol Json Structure protocol instance.
> + @param[in] Uri Target URI.
> + @param[out] SchemaInfo Returned schema information.
> +
> + @retval EFI_SUCCESS Schema information is returned successfully.
> + @retval Others Errors occur.
> +
> +**/
> +EFI_STATUS
> +GetRedfishSchemaInfo (
> + IN REDFISH_SERVICE *RedfishService,
> + IN EFI_REST_JSON_STRUCTURE_PROTOCOL *JsonStructProtocol,
> + IN CHAR8 *Uri,
> + OUT REDFISH_SCHEMA_INFO *SchemaInfo
> + );
> +
> +/**
> +
> + Get the property name by given Configure Langauge.
> +
> + @param[in] ConfigureLang Configure Language string.
> +
> + @retval EFI_STRING Pointer to property name.
> + @retval NULL There is error.
> +
> +**/
> +EFI_STRING
> +GetPropertyFromConfigureLang (
> + IN EFI_STRING ConfigureLang
> + );
> +
> +/**
> +
> + Get the property value in string type.
> +
> + @param[in] Schema Schema of this property.
> + @param[in] Version Schema version.
> + @param[in] PropertyName Property name.
> + @param[in] ConfigureLang Configure Language of this property.
> +
> + @retval CHAR8* Pointer to the CHAR8 buffer.
> + @retval NULL There is error.
> +
> +**/
> +CHAR8 *
> +GetPropertyStringValue (
> + IN CHAR8 *Schema,
> + IN CHAR8 *Version,
> + IN EFI_STRING PropertyName,
> + IN EFI_STRING ConfigureLang
> + );
> +
> +/**
> +
> + Get the property value in numeric type.
> +
> + @param[in] Schema Schema of this property.
> + @param[in] Version Schema version.
> + @param[in] PropertyName Property name.
> + @param[in] ConfigureLang Configure Language of this property.
> +
> + @retval INT64* Pointer to the INT64 value.
> + @retval NULL There is error.
> +
> +**/
> +INT64 *
> +GetPropertyNumericValue (
> + IN CHAR8 *Schema,
> + IN CHAR8 *Version,
> + IN EFI_STRING PropertyName,
> + IN EFI_STRING ConfigureLang
> + );
> +
> +/**
> +
> + Get the property value in Boolean type.
> +
> + @param[in] Schema Schema of this property.
> + @param[in] Version Schema version.
> + @param[in] PropertyName Property name.
> + @param[in] ConfigureLang Configure Language of this property.
> +
> + @retval BOOLEAN Boolean value returned by this property.
> +
> +**/
> +BOOLEAN *
> +GetPropertyBooleanValue (
> + IN CHAR8 *Schema,
> + IN CHAR8 *Version,
> + IN EFI_STRING PropertyName,
> + IN EFI_STRING ConfigureLang
> + );
> +
> +/**
> +
> + Check and see if we need to do provisioning for this property.
> +
> + @param[in] PropertyBuffer Pointer to property instance.
> + @param[in] ProvisionMode TRUE if we are in provision mode. FALSE
> otherwise.
> +
> + @retval TRUE Provision is required.
> + @retval FALSE Provision is not required.
> +
> +**/
> +BOOLEAN
> +PropertyChecker (
> + IN VOID *PropertyBuffer,
> + IN BOOLEAN ProvisionMode
> + );
> +
> +/**
> +
> + Check and see if we need to do provisioning for this two properties.
> +
> + @param[in] PropertyBuffer1 Pointer to property instance 1.
> + @param[in] PropertyBuffer2 Pointer to property instance 2.
> + @param[in] ProvisionMode TRUE if we are in provision mode. FALSE
> otherwise.
> +
> + @retval TRUE Provision is required.
> + @retval FALSE Provision is not required.
> +
> +**/
> +BOOLEAN
> +PropertyChecker2Parm (
> + IN VOID *PropertyBuffer1,
> + IN VOID *PropertyBuffer2,
> + IN BOOLEAN ProvisionMode
> + );
> +
> +/**
> +
> + Keep ETAG string and URI string in database.
> +
> + @param[in] EtagStr ETAG string.
> + @param[in] Uri URI string.
> +
> + @retval EFI_SUCCESS ETAG and URI are applied successfully.
> + @retval Others Errors occur.
> +
> +**/
> +EFI_STATUS
> +SetEtagWithUri (
> + IN CHAR8 *EtagStr,
> + IN CHAR8 *Uri
> + );
> +
> +/**
> +
> + Find ETAG string that refers to given URI.
> +
> + @param[in] Uri Target URI string.
> +
> + @retval CHAR8 * ETAG string
> + @retval NULL No ETAG is found.
> +
> +**/
> +CHAR8 *
> +GetEtagWithUri (
> + IN CHAR8 *Uri
> + );
> +
> +#endif
> diff --git
> a/RedfishClientPkg/Library/RedfishFeatureUtilityLib/RedfishFeatureUtilityInt
> ernal.h
> b/RedfishClientPkg/Library/RedfishFeatureUtilityLib/RedfishFeatureUtilityInt
> ernal.h
> new file mode 100644
> index 00000000..cfb9759a
> --- /dev/null
> +++
> b/RedfishClientPkg/Library/RedfishFeatureUtilityLib/RedfishFeatureUtilityInt
> ernal.h
> @@ -0,0 +1,45 @@
> +/** @file
> + Common header file for RedfishFeatureUtilityLib driver.
> +
> + (C) Copyright 2020-2021 Hewlett Packard Enterprise Development LP<BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef REDFISH_FEATURE_INTERNAL_H_
> +#define REDFISH_FEATURE_INTERNAL_H_
> +
> +#include <Uefi.h>
> +
> +#include <Library/BaseLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/JsonLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/PrintLib.h>
> +#include <Library/PcdLib.h>
> +#include <Library/RedfishLib.h>
> +#include <Library/RedfishFeatureUtilityLib.h>
> +#include <Library/RedfishPlatformConfigLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/UefiRuntimeServicesTableLib.h>
> +#include <Library/UefiLib.h>
> +
> +#include <Guid/VariableFormat.h>
> +
> +#include <Protocol/EdkIIRedfishETagProtocol.h>
> +
> +#define INDEX_VARIABLE_SIZE 64
> +#define INDEX_STRING_SIZE 16
> +#define IS_EMPTY_STRING(a) (a == NULL || a[0] == '\0')
> +#define INDEX_STRING L"{%d}"
> +#define SCHEMA_NAME_PREFIX_OFFSET 15// x-uefi-redfish-
> +#define REDFISH_SYSTEM_ROOT_PATH "/v1/Systems[UUID~%g]"
> +#define MAX_CONF_LANG_LEN 128
> +
> +#define BIOS_CONFIG_TO_REDFISH_REDPATH_ARRAY_START_SIGNATURE
> L"{"
> +#define BIOS_CONFIG_TO_REDFISH_REDPATH_ARRAY_END_SIGNATURE
> L"}"
> +#define BIOS_CONFIG_TO_REDFISH_REDPATH_POOL_SIZE 64
> +
> +#endif
> diff --git
> a/RedfishClientPkg/Library/RedfishFeatureUtilityLib/RedfishFeatureUtilityLib
> .c
> b/RedfishClientPkg/Library/RedfishFeatureUtilityLib/RedfishFeatureUtilityLib
> .c
> new file mode 100644
> index 00000000..605283b9
> --- /dev/null
> +++
> b/RedfishClientPkg/Library/RedfishFeatureUtilityLib/RedfishFeatureUtilityLib
> .c
> @@ -0,0 +1,1513 @@
> +/** @file
> + Redfish feature utility library implementation
> +
> + (C) Copyright 2020-2021 Hewlett Packard Enterprise Development LP<BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include "RedfishFeatureUtilityInternal.h"
> +
> +EDKII_REDFISH_ETAG_PROTOCOL *mEtagProtocol;
> +
> +/**
> +
> + Get array key by parsing the URI.
> +
> + @param[in] Uri URI with array key.
> + @param[out] ArrayKey Array key in given URI string.
> +
> + @retval EFI_SUCCESS Array key is found.
> + @retval Others Errors occur.
> +
> +**/
> +EFI_STATUS
> +GetArraykeyFromUri (
> + IN CHAR8 *Uri,
> + OUT CHAR8 **ArrayKey
> + )
> +{
> + CHAR8 *LeftBracket;
> + UINTN Index;
> +
> + if (IS_EMPTY_STRING (Uri) || (ArrayKey == NULL)) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + *ArrayKey = NULL;
> +
> + //
> + // Loop through Uri and find last '['
> + //
> + LeftBracket = NULL;
> + for (Index = 0; Uri[Index] != '\0'; Index++) {
> + if (Uri[Index] == '[') {
> + LeftBracket = &Uri[Index];
> + }
> + }
> +
> + if (LeftBracket == NULL) {
> + return EFI_NOT_FOUND;
> + }
> +
> + //
> + // skip '/'
> + //
> + ++LeftBracket;
> +
> + *ArrayKey = AllocateCopyPool (AsciiStrSize (LeftBracket), LeftBracket);
> + if (*ArrayKey == NULL) {
> + return EFI_OUT_OF_RESOURCES;
> + }
> +
> + //
> + // remove ']'
> + //
> + *(*ArrayKey + AsciiStrLen (*ArrayKey) - 1) = '\0';
> +
> + return EFI_SUCCESS;
> +}
> +
> +/**
> +
> + Keep configure language with given key in UEFI variable.
> +
> + @param[in] Schema Schema name.
> + @param[in] Version Schema version.
> + @param[in] Key Key string.
> + @param[in] ConfigureLangIndex Index value.
> +
> + @retval EFI_SUCCESS Data is saved in UEFI variable.
> + @retval Others Errors occur.
> +
> +**/
> +EFI_STATUS
> +SetConfigureLangWithkey (
> + IN CHAR8 *Schema,
> + IN CHAR8 *Version,
> + IN CHAR8 *Key,
> + IN UINTN ConfigureLangIndex
> + )
> +{
> + CHAR16 IndexString[INDEX_STRING_SIZE];
> + CHAR16 VarName[INDEX_VARIABLE_SIZE];
> + CHAR16 *VarData;
> + EFI_STATUS Status;
> +
> + //
> + // Variable content.
> + //
> + UnicodeSPrint (IndexString, sizeof (IndexString), INDEX_STRING,
> ConfigureLangIndex);
> +
> + //
> + // Variable name.
> + //
> + UnicodeSPrint (VarName, sizeof (VarName), L"%a_%a_%a", Schema,
> Version, Key);
> +
> + //
> + // Check if it exists already.
> + //
> + Status = GetVariable2 (
> + VarName,
> + &gEfiCallerIdGuid,
> + (VOID *)&VarData,
> + NULL
> + );
> + if (!EFI_ERROR (Status)) {
> + DEBUG ((DEBUG_INFO, "%a, remove stale data: %s\n", __FUNCTION__,
> VarData));
> + FreePool (VarData);
> + gRT->SetVariable (VarName, &gEfiCallerIdGuid,
> VARIABLE_ATTRIBUTE_NV_BS, 0, NULL);
> + }
> +
> + return gRT->SetVariable (VarName, &gEfiCallerIdGuid,
> VARIABLE_ATTRIBUTE_NV_BS, StrSize (IndexString), (VOID *)&IndexString);
> +}
> +
> +/**
> +
> + Find configure language with input key string.
> +
> + @param[in] Schema Schema name.
> + @param[in] Version Schema version.
> + @param[in] Property Property name.
> + @param[in] Key Key string.
> +
> + @retval CHAR16 * Corresponding configure langauge
> + @retval NULL No configure language is found
> +
> +**/
> +CHAR16 *
> +GetConfigureLangByKey (
> + IN CHAR8 *Schema,
> + IN CHAR8 *Version,
> + IN CHAR8 *Property, OPTIONAL
> + IN CHAR8 *Key
> + )
> +{
> + EFI_STATUS Status;
> + CHAR16 VariableName[64];
> + UINTN VariableSize;
> + CHAR16 *CollectionIndex;
> + CHAR16 *ConfigureLang;
> + UINTN ConfigureLangLen;
> +
> + if ((Schema == NULL) || (Version == NULL) || (Key == NULL)) {
> + return NULL;
> + }
> +
> + CollectionIndex = NULL;
> + ConfigureLang = NULL;
> +
> + UnicodeSPrint (VariableName, 64, L"%a_%a_%a", Schema, Version, Key);
> +
> + Status = GetVariable2 (
> + VariableName,
> + &gEfiCallerIdGuid,
> + (VOID *)&CollectionIndex,
> + &VariableSize
> + );
> + if (EFI_ERROR (Status)) {
> + return NULL;
> + }
> +
> + ConfigureLangLen = AsciiStrLen (Schema) + StrLen (CollectionIndex) +
> (Property == NULL ? 0 : AsciiStrLen (Property)) + 3 + 1;
> + ConfigureLang = AllocatePool (sizeof (CHAR16) * ConfigureLangLen);
> + ASSERT (ConfigureLang);
> +
> + if (Property != NULL) {
> + UnicodeSPrint (ConfigureLang, sizeof (CHAR16) * ConfigureLangLen,
> L"/%a/%s/%a", Schema, CollectionIndex, Property);
> + } else {
> + UnicodeSPrint (ConfigureLang, sizeof (CHAR16) * ConfigureLangLen,
> L"/%a/%s", Schema, CollectionIndex);
> + }
> +
> + FreePool (CollectionIndex);
> +
> + return ConfigureLang;
> +}
> +
> +/**
> +
> + Keep ETAG string and URI string in database.
> +
> + @param[in] EtagStr ETAG string.
> + @param[in] Uri URI string.
> +
> + @retval EFI_SUCCESS ETAG and URI are applied successfully.
> + @retval Others Errors occur.
> +
> +**/
> +EFI_STATUS
> +SetEtagWithUri (
> + IN CHAR8 *EtagStr,
> + IN CHAR8 *Uri
> + )
> +{
> + EFI_STATUS Status;
> +
> + if (IS_EMPTY_STRING (EtagStr) || IS_EMPTY_STRING (Uri)) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + if (mEtagProtocol == NULL) {
> + Status = gBS->LocateProtocol (
> + &gEdkIIRedfishETagProtocolGuid,
> + NULL,
> + (VOID **)&mEtagProtocol
> + );
> + if (EFI_ERROR (Status)) {
> + return Status;
> + }
> + }
> +
> + mEtagProtocol->Set (mEtagProtocol, Uri, EtagStr);
> + mEtagProtocol->Flush (mEtagProtocol);
> +
> + return EFI_SUCCESS;
> +}
> +
> +/**
> +
> + Find ETAG string that refers to given URI.
> +
> + @param[in] Uri Target URI string.
> +
> + @retval CHAR8 * ETAG string
> + @retval NULL No ETAG is found.
> +
> +**/
> +CHAR8 *
> +GetEtagWithUri (
> + IN CHAR8 *Uri
> + )
> +{
> + EFI_STATUS Status;
> + CHAR8 *EtagStr;
> +
> + if (IS_EMPTY_STRING (Uri)) {
> + return NULL;
> + }
> +
> + if (mEtagProtocol == NULL) {
> + Status = gBS->LocateProtocol (
> + &gEdkIIRedfishETagProtocolGuid,
> + NULL,
> + (VOID **)&mEtagProtocol
> + );
> + if (EFI_ERROR (Status)) {
> + return NULL;
> + }
> + }
> +
> + Status = mEtagProtocol->Get (mEtagProtocol, Uri, &EtagStr);
> + if (EFI_ERROR (Status)) {
> + return NULL;
> + }
> +
> + return EtagStr;
> +}
> +
> +/**
> +
> + Convert HII string value to string value in JSON format.
> +
> + @param[in] HiiStringValue String in HII format.
> +
> + @retval CHAR8 * String in JSON format.
> + @retval NULL Errors occur.
> +
> +**/
> +CHAR8 *
> +ConvertHiiStringValueToJsonStringValue (
> + IN EFI_STRING HiiStringValue
> + )
> +{
> + CHAR8 *JsonValue;
> + UINTN JsonValueSize;
> +
> + if (IS_EMPTY_STRING (HiiStringValue)) {
> + return NULL;
> + }
> +
> + JsonValueSize = StrLen (HiiStringValue) + 1;
> + JsonValue = AllocatePool (JsonValueSize);
> + UnicodeStrToAsciiStrS (HiiStringValue, JsonValue, JsonValueSize);
> +
> + return JsonValue;
> +}
> +
> +/**
> +
> + Apply property value to UEFI HII database in string type.
> +
> + @param[in] Schema Property schema.
> + @param[in] Version Property schema version.
> + @param[in] ConfigureLang Configure language refers to this property.
> + @param[in] FeatureValue New value to set.
> +
> + @retval EFI_SUCCESS New value is applied successfully.
> + @retval Others Errors occur.
> +
> +**/
> +EFI_STATUS
> +ApplyFeatureSettingsStringType (
> + IN CHAR8 *Schema,
> + IN CHAR8 *Version,
> + IN EFI_STRING ConfigureLang,
> + IN CHAR8 *FeatureValue
> + )
> +{
> + EFI_STATUS Status;
> + EDKII_REDFISH_VALUE RedfishValue;
> +
> + if (IS_EMPTY_STRING (Schema) || IS_EMPTY_STRING (Version) ||
> IS_EMPTY_STRING (ConfigureLang) || (FeatureValue == NULL)) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + //
> + // Get the current value from HII
> + //
> + Status = RedfishPlatformConfigGetValue (Schema, Version, ConfigureLang,
> &RedfishValue);
> + if (EFI_ERROR (Status)) {
> + DEBUG ((DEBUG_ERROR, "%a, %a.%a %s failed: %r\n", __FUNCTION__,
> Schema, Version, ConfigureLang, Status));
> + } else {
> + if (RedfishValue.Type != REDFISH_VALUE_TYPE_STRING) {
> + DEBUG ((DEBUG_ERROR, "%a, %a.%a %s value is not string type\n",
> __FUNCTION__, Schema, Version, ConfigureLang));
> + return EFI_DEVICE_ERROR;
> + }
> +
> + if (AsciiStrCmp (FeatureValue, RedfishValue.Value.Buffer) != 0) {
> + //
> + // Apply settings from redfish
> + //
> + DEBUG ((DEBUG_INFO, "%a, %a.%a apply %s from %a to %a\n",
> __FUNCTION__, Schema, Version, ConfigureLang,
> RedfishValue.Value.Buffer, FeatureValue));
> +
> + FreePool (RedfishValue.Value.Buffer);
> + RedfishValue.Value.Buffer = FeatureValue;
> +
> + Status = RedfishPlatformConfigSetValue (Schema, Version,
> ConfigureLang, RedfishValue);
> + if (EFI_ERROR (Status)) {
> + DEBUG ((DEBUG_ERROR, "%a, apply %s to %s failed: %r\n",
> __FUNCTION__, ConfigureLang, FeatureValue, Status));
> + }
> + } else {
> + DEBUG ((DEBUG_ERROR, "%a, %a.%a %s value is: %s\n",
> __FUNCTION__, Schema, Version, ConfigureLang,
> RedfishValue.Value.Buffer, Status));
> + }
> + }
> +
> + return Status;
> +}
> +
> +/**
> +
> + Apply property value to UEFI HII database in numric type.
> +
> + @param[in] Schema Property schema.
> + @param[in] Version Property schema version.
> + @param[in] ConfigureLang Configure language refers to this property.
> + @param[in] FeatureValue New value to set.
> +
> + @retval EFI_SUCCESS New value is applied successfully.
> + @retval Others Errors occur.
> +
> +**/
> +EFI_STATUS
> +ApplyFeatureSettingsNumericType (
> + IN CHAR8 *Schema,
> + IN CHAR8 *Version,
> + IN EFI_STRING ConfigureLang,
> + IN INTN FeatureValue
> + )
> +{
> + EFI_STATUS Status;
> + EDKII_REDFISH_VALUE RedfishValue;
> +
> + if (IS_EMPTY_STRING (Schema) || IS_EMPTY_STRING (Version) ||
> IS_EMPTY_STRING (ConfigureLang)) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + //
> + // Get the current value from HII
> + //
> + Status = RedfishPlatformConfigGetValue (Schema, Version, ConfigureLang,
> &RedfishValue);
> + if (EFI_ERROR (Status)) {
> + DEBUG ((DEBUG_ERROR, "%a, %a.%a %s failed: %r\n", __FUNCTION__,
> Schema, Version, ConfigureLang, Status));
> + } else {
> + if (RedfishValue.Type != REDFISH_VALUE_TYPE_INTEGER) {
> + DEBUG ((DEBUG_ERROR, "%a, %a.%a %s value is not numeric type\n",
> __FUNCTION__, Schema, Version, ConfigureLang));
> + return EFI_DEVICE_ERROR;
> + }
> +
> + if (RedfishValue.Value.Integer != FeatureValue) {
> + //
> + // Apply settings from redfish
> + //
> + DEBUG ((DEBUG_INFO, "%a, %a.%a apply %s from 0x%x to 0x%x\n",
> __FUNCTION__, Schema, Version, ConfigureLang,
> RedfishValue.Value.Integer, FeatureValue));
> +
> + RedfishValue.Value.Integer = (INT64)FeatureValue;
> +
> + Status = RedfishPlatformConfigSetValue (Schema, Version,
> ConfigureLang, RedfishValue);
> + if (EFI_ERROR (Status)) {
> + DEBUG ((DEBUG_ERROR, "%a, apply %s to 0x%x failed: %r\n",
> __FUNCTION__, ConfigureLang, FeatureValue, Status));
> + }
> + } else {
> + DEBUG ((DEBUG_ERROR, "%a, %a.%a %s value is: 0x%x\n",
> __FUNCTION__, Schema, Version, ConfigureLang,
> RedfishValue.Value.Integer, Status));
> + }
> + }
> +
> + return Status;
> +}
> +
> +/**
> +
> + Apply property value to UEFI HII database in boolean type.
> +
> + @param[in] Schema Property schema.
> + @param[in] Version Property schema version.
> + @param[in] ConfigureLang Configure language refers to this property.
> + @param[in] FeatureValue New value to set.
> +
> + @retval EFI_SUCCESS New value is applied successfully.
> + @retval Others Errors occur.
> +
> +**/
> +EFI_STATUS
> +ApplyFeatureSettingsBooleanType (
> + IN CHAR8 *Schema,
> + IN CHAR8 *Version,
> + IN EFI_STRING ConfigureLang,
> + IN BOOLEAN FeatureValue
> + )
> +{
> + EFI_STATUS Status;
> + EDKII_REDFISH_VALUE RedfishValue;
> +
> + if (IS_EMPTY_STRING (Schema) || IS_EMPTY_STRING (Version) ||
> IS_EMPTY_STRING (ConfigureLang)) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + //
> + // Get the current value from HII
> + //
> + Status = RedfishPlatformConfigGetValue (Schema, Version, ConfigureLang,
> &RedfishValue);
> + if (EFI_ERROR (Status)) {
> + DEBUG ((DEBUG_ERROR, "%a, %a.%a %s failed: %r\n", __FUNCTION__,
> Schema, Version, ConfigureLang, Status));
> + } else {
> + if (RedfishValue.Type != REDFISH_VALUE_TYPE_BOOLEAN) {
> + DEBUG ((DEBUG_ERROR, "%a, %a.%a %s value is not boolean type\n",
> __FUNCTION__, Schema, Version, ConfigureLang));
> + return EFI_DEVICE_ERROR;
> + }
> +
> + if (RedfishValue.Value.Boolean != FeatureValue) {
> + //
> + // Apply settings from redfish
> + //
> + DEBUG ((DEBUG_INFO, "%a, %a.%a apply %s from %a to %a\n",
> __FUNCTION__, Schema, Version, ConfigureLang,
> (RedfishValue.Value.Boolean ? "True" : "False"), (FeatureValue ? "True" :
> "False")));
> +
> + RedfishValue.Value.Boolean = FeatureValue;
> +
> + Status = RedfishPlatformConfigSetValue (Schema, Version,
> ConfigureLang, RedfishValue);
> + if (EFI_ERROR (Status)) {
> + DEBUG ((DEBUG_ERROR, "%a, apply %s to %a failed: %r\n",
> __FUNCTION__, ConfigureLang, (FeatureValue ? "True" : "False"), Status));
> + }
> + } else {
> + DEBUG ((DEBUG_ERROR, "%a, %a.%a %s value is: %a\n",
> __FUNCTION__, Schema, Version, ConfigureLang,
> (RedfishValue.Value.Boolean ? "True" : "False"), Status));
> + }
> + }
> +
> + return Status;
> +}
> +
> +/**
> +
> + Read redfish resource by given resource path.
> +
> + @param[in] Service Redfish srvice instacne to make query.
> + @param[in] ResourcePath Target resource path.
> + @param[out] Response HTTP response from redfish service.
> +
> + @retval EFI_SUCCESS Resrouce is returned successfully.
> + @retval Others Errors occur.
> +
> +**/
> +EFI_STATUS
> +GetResourceByPath (
> + IN REDFISH_SERVICE *Service,
> + IN CHAR8 *ResourcePath,
> + OUT REDFISH_RESPONSE *Response
> + )
> +{
> + EFI_STATUS Status;
> +
> + if ((Service == NULL) || (Response == NULL) || IS_EMPTY_STRING
> (ResourcePath)) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + //
> + // Get resource from redfish service.
> + //
> + Status = RedfishGetByService (
> + Service,
> + ResourcePath,
> + Response
> + );
> + if (EFI_ERROR (Status)) {
> + DEBUG ((DEBUG_ERROR, "%a, RedfishGetByService to %a failed: %r\n",
> __FUNCTION__, ResourcePath, Status));
> + if (Response->Payload != NULL) {
> + RedfishDumpPayload (Response->Payload);
> + RedfishFreeResponse (
> + NULL,
> + 0,
> + NULL,
> + Response->Payload
> + );
> + Response->Payload = NULL;
> + }
> +
> + return Status;
> + }
> +
> + return EFI_SUCCESS;
> +}
> +
> +/**
> +
> + Find array index from given configure language string.
> +
> + @param[in] ConfigureLang Configure language string to parse.
> + @param[out] UnifiedConfigureLang The configure language in array.
> + @param[out] Index The array index number.
> +
> + @retval EFI_SUCCESS Index is found.
> + @retval Others Errors occur.
> +
> +**/
> +EFI_STATUS
> +GetArrayIndexFromArrayTypeConfigureLang (
> + IN CHAR16 *ConfigureLang,
> + OUT CHAR16 **UnifiedConfigureLang,
> + OUT UINTN *Index
> + )
> +{
> + CHAR16 *TmpConfigureLang;
> + CHAR16 *IndexString;
> + CHAR16 *TmpString;
> +
> + if ((ConfigureLang == NULL) || (UnifiedConfigureLang == NULL) || (Index
> == NULL)) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + TmpConfigureLang = AllocateCopyPool (StrSize (ConfigureLang),
> ConfigureLang);
> + if (TmpConfigureLang == NULL) {
> + return EFI_OUT_OF_RESOURCES;
> + }
> +
> + //
> + // looking for index signature "{""
> + //
> + IndexString = StrStr (TmpConfigureLang,
> BIOS_CONFIG_TO_REDFISH_REDPATH_ARRAY_START_SIGNATURE);
> + if (IndexString == NULL) {
> + return EFI_NOT_FOUND;
> + }
> +
> + //
> + // Skip "{"
> + //
> + TmpString = IndexString + StrLen
> (BIOS_CONFIG_TO_REDFISH_REDPATH_ARRAY_START_SIGNATURE);
> +
> + //
> + // Looking for "}"
> + //
> + TmpString = StrStr (TmpString,
> BIOS_CONFIG_TO_REDFISH_REDPATH_ARRAY_END_SIGNATURE);
> + if (TmpString == NULL) {
> + return EFI_NOT_FOUND;
> + }
> +
> + //
> + // Append '\0' for converting decimal string to integer.
> + //
> + TmpString[0] = '\0';
> +
> + //
> + // Convert decimal string to integer
> + //
> + *Index = StrDecimalToUintn (IndexString + StrLen
> (BIOS_CONFIG_TO_REDFISH_REDPATH_ARRAY_START_SIGNATURE));
> +
> + //
> + // Resotre the '}' character and remove rest of string.
> + //
> + TmpString[0] = L'}';
> + TmpString[1] = '\0';
> +
> + *UnifiedConfigureLang = TmpConfigureLang;
> +
> + return EFI_SUCCESS;
> +}
> +
> +/**
> +
> + Search HII database with given Configure Language pattern. Data is
> handled and
> + returned in array.
> +
> + @param[in] Schema The schema to search.
> + @param[in] Version The schema version.
> + @param[in] Pattern Configure Language pattern to search.
> + @param[out] UnifiedConfigureLangList The data returned by HII database.
> +
> + @retval EFI_SUCCESS Data is found and returned.
> + @retval Others Errors occur.
> +
> +**/
> +EFI_STATUS
> +RedfishFeatureGetUnifiedArrayTypeConfigureLang (
> + IN CHAR8 *Schema,
> + IN CHAR8 *Version,
> + IN EFI_STRING Pattern, OPTIONAL
> + OUT REDFISH_FEATURE_ARRAY_TYPE_CONFIG_LANG_LIST
> *UnifiedConfigureLangList
> + )
> +{
> + EFI_STATUS Status;
> + EFI_STRING *ConfigureLangList;
> + UINTN Count;
> + UINTN Index;
> + UINTN Index2;
> + UINTN ArrayIndex;
> + EFI_STRING UnifiedConfigureLang;
> + BOOLEAN Duplicated;
> + REDFISH_FEATURE_ARRAY_TYPE_CONFIG_LANG
> UnifiedConfigureLangPool[BIOS_CONFIG_TO_REDFISH_REDPATH_POOL_SIZ
> E];
> +
> + if (IS_EMPTY_STRING (Schema) || IS_EMPTY_STRING (Version) ||
> (UnifiedConfigureLangList == NULL)) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + UnifiedConfigureLangList->Count = 0;
> + UnifiedConfigureLangList->List = NULL;
> + ZeroMem (UnifiedConfigureLangPool, sizeof (UnifiedConfigureLangPool));
> +
> + Status = RedfishPlatformConfigGetConfigureLang (Schema, Version,
> Pattern, &ConfigureLangList, &Count);
> + if (EFI_ERROR (Status)) {
> + DEBUG ((DEBUG_ERROR, "%a, RedfishFeatureGetConfigureLangRegex
> failed: %r\n", __FUNCTION__, Status));
> + return Status;
> + }
> +
> + if (Count == 0) {
> + return EFI_NOT_FOUND;
> + }
> +
> + for (Index = 0; Index < Count; Index++) {
> + Status = GetArrayIndexFromArrayTypeConfigureLang
> (ConfigureLangList[Index], &UnifiedConfigureLang, &ArrayIndex);
> + if (EFI_ERROR (Status)) {
> + ASSERT (FALSE);
> + continue;
> + }
> +
> + //
> + // Check if this configure language is duplicated.
> + //
> + Duplicated = FALSE;
> + for (Index2 = 0; Index2 <
> BIOS_CONFIG_TO_REDFISH_REDPATH_POOL_SIZE; Index2++) {
> + if (UnifiedConfigureLangPool[Index2].ConfigureLang == NULL) {
> + break;
> + }
> +
> + if (StrCmp (UnifiedConfigureLangPool[Index2].ConfigureLang,
> UnifiedConfigureLang) == 0) {
> + Duplicated = TRUE;
> + break;
> + }
> + }
> +
> + if (Duplicated) {
> + FreePool (UnifiedConfigureLang);
> + continue;
> + }
> +
> + if (UnifiedConfigureLangList->Count >=
> BIOS_CONFIG_TO_REDFISH_REDPATH_POOL_SIZE) {
> + FreePool (UnifiedConfigureLang);
> + Status = EFI_BUFFER_TOO_SMALL;
> + break;
> + }
> +
> + //
> + // New configure language. Keep it in Pool
> + //
> +
> + UnifiedConfigureLangPool[UnifiedConfigureLangList-
> >Count].ConfigureLang = UnifiedConfigureLang;
> + UnifiedConfigureLangPool[UnifiedConfigureLangList->Count].Index =
> ArrayIndex;
> + ++UnifiedConfigureLangList->Count;
> + }
> +
> + FreePool (ConfigureLangList);
> +
> + //
> + // Prepare the result to caller.
> + //
> + UnifiedConfigureLangList->List = AllocateCopyPool (sizeof
> (REDFISH_FEATURE_ARRAY_TYPE_CONFIG_LANG) *
> UnifiedConfigureLangList->Count, UnifiedConfigureLangPool);
> +
> + return Status;
> +}
> +
> +/**
> +
> + Create HTTP payload and send them to redfish service with PATCH method.
> +
> + @param[in] Service Redfish service.
> + @param[in] TargetPayload Target payload
> + @param[in] Json Data in JSON format.
> + @param[out] Etag Returned ETAG string from Redfish service.
> +
> + @retval EFI_SUCCESS Data is sent to redfish service successfully.
> + @retval Others Errors occur.
> +
> +**/
> +EFI_STATUS
> +CreatePayloadToPatchResource (
> + IN REDFISH_SERVICE *Service,
> + IN REDFISH_PAYLOAD *TargetPayload,
> + IN CHAR8 *Json,
> + OUT CHAR8 **Etag
> + )
> +{
> + REDFISH_PAYLOAD Payload;
> + EDKII_JSON_VALUE ResourceJsonValue;
> + REDFISH_RESPONSE PostResponse;
> + EFI_STATUS Status;
> + UINTN Index;
> + EDKII_JSON_VALUE JsonValue;
> + EDKII_JSON_VALUE OdataIdValue;
> + CHAR8 *OdataIdString;
> +
> + if ((Service == NULL) || (TargetPayload == NULL) || IS_EMPTY_STRING
> (Json) || (Etag == NULL)) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + ResourceJsonValue = JsonLoadString (Json, 0, NULL);
> + Payload = RedfishCreatePayload (ResourceJsonValue, Service);
> + if (Payload == NULL) {
> + DEBUG ((DEBUG_ERROR, "%a:%d Failed to create JSON payload from
> JSON value!\n", __FUNCTION__, __LINE__));
> + Status = EFI_DEVICE_ERROR;
> + goto EXIT_FREE_JSON_VALUE;
> + }
> +
> + ZeroMem (&PostResponse, sizeof (REDFISH_RESPONSE));
> + Status = RedfishPatchToPayload (TargetPayload, Payload, &PostResponse);
> + if (EFI_ERROR (Status)) {
> + DEBUG ((DEBUG_ERROR, "%a:%d Failed to PATCH payload to Redfish
> service.\n", __FUNCTION__, __LINE__));
> + goto EXIT_FREE_JSON_VALUE;
> + }
> +
> + //
> + // Keep etag.
> + //
> + *Etag = NULL;
> + if (*PostResponse.StatusCode == HTTP_STATUS_200_OK) {
> + if (PostResponse.HeaderCount != 0) {
> + for (Index = 0; Index < PostResponse.HeaderCount; Index++) {
> + if (AsciiStrnCmp (PostResponse.Headers[Index].FieldName, "ETag", 4)
> == 0) {
> + *Etag = AllocateCopyPool (AsciiStrSize
> (PostResponse.Headers[Index].FieldValue),
> PostResponse.Headers[Index].FieldValue);
> + }
> + }
> + } else if (PostResponse.Payload != NULL) {
> + //
> + // No header is returned. Search payload for location.
> + //
> + JsonValue = RedfishJsonInPayload (PostResponse.Payload);
> + if (JsonValue != NULL) {
> + OdataIdValue = JsonObjectGetValue (JsonValueGetObject (JsonValue),
> "@odata.etag");
> + if (OdataIdValue != NULL) {
> + OdataIdString = (CHAR8 *)JsonValueGetAsciiString (OdataIdValue);
> + if (OdataIdString != NULL) {
> + *Etag = AllocateCopyPool (AsciiStrSize (OdataIdString), OdataIdString);
> + }
> + }
> + }
> + }
> + }
> +
> + RedfishFreeResponse (
> + PostResponse.StatusCode,
> + PostResponse.HeaderCount,
> + PostResponse.Headers,
> + PostResponse.Payload
> + );
> +
> +EXIT_FREE_JSON_VALUE:
> + if (Payload != NULL) {
> + RedfishCleanupPayload (Payload);
> + }
> +
> + JsonValueFree (ResourceJsonValue);
> +
> + return Status;
> +}
> +
> +/**
> +
> + Create HTTP payload and send them to redfish service with POST method.
> +
> + @param[in] Service Redfish service.
> + @param[in] TargetPayload Target payload
> + @param[in] Json Data in JSON format.
> + @param[out] Location Returned location string from Redfish service.
> + @param[out] Etag Returned ETAG string from Redfish service.
> +
> + @retval EFI_SUCCESS Data is sent to redfish service successfully.
> + @retval Others Errors occur.
> +
> +**/
> +EFI_STATUS
> +CreatePayloadToPostResource (
> + IN REDFISH_SERVICE *Service,
> + IN REDFISH_PAYLOAD *TargetPayload,
> + IN CHAR8 *Json,
> + OUT CHAR8 **Location,
> + OUT CHAR8 **Etag
> + )
> +{
> + REDFISH_PAYLOAD Payload;
> + EDKII_JSON_VALUE ResourceJsonValue;
> + REDFISH_RESPONSE PostResponse;
> + EFI_STATUS Status;
> + UINTN Index;
> + EDKII_JSON_VALUE JsonValue;
> + EDKII_JSON_VALUE OdataIdValue;
> + CHAR8 *OdataIdString;
> +
> + if ((Service == NULL) || (TargetPayload == NULL) || IS_EMPTY_STRING
> (Json) || (Location == NULL) || (Etag == NULL)) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + ResourceJsonValue = JsonLoadString (Json, 0, NULL);
> + Payload = RedfishCreatePayload (ResourceJsonValue, Service);
> + if (Payload == NULL) {
> + DEBUG ((DEBUG_ERROR, "%a:%d Failed to create JSON payload from
> JSON value!\n", __FUNCTION__, __LINE__));
> + Status = EFI_DEVICE_ERROR;
> + goto EXIT_FREE_JSON_VALUE;
> + }
> +
> + ZeroMem (&PostResponse, sizeof (REDFISH_RESPONSE));
> + Status = RedfishPostToPayload (TargetPayload, Payload, &PostResponse);
> + if (EFI_ERROR (Status)) {
> + DEBUG ((DEBUG_ERROR, "%a:%d Failed to POST Attribute Registry to
> Redfish service.\n", __FUNCTION__, __LINE__));
> + goto EXIT_FREE_JSON_VALUE;
> + }
> +
> + //
> + // per Redfish spec. the URL of new eresource will be returned in
> "Location" header.
> + //
> + *Location = NULL;
> + *Etag = NULL;
> + if (*PostResponse.StatusCode == HTTP_STATUS_200_OK) {
> + if (PostResponse.HeaderCount != 0) {
> + for (Index = 0; Index < PostResponse.HeaderCount; Index++) {
> + if (AsciiStrnCmp (PostResponse.Headers[Index].FieldName, "Location",
> 8) == 0) {
> + *Location = AllocateCopyPool (AsciiStrSize
> (PostResponse.Headers[Index].FieldValue),
> PostResponse.Headers[Index].FieldValue);
> + } else if (AsciiStrnCmp (PostResponse.Headers[Index].FieldName,
> "ETag", 4) == 0) {
> + *Etag = AllocateCopyPool (AsciiStrSize
> (PostResponse.Headers[Index].FieldValue),
> PostResponse.Headers[Index].FieldValue);
> + }
> + }
> + } else if (PostResponse.Payload != NULL) {
> + //
> + // No header is returned. Search payload for location.
> + //
> + JsonValue = RedfishJsonInPayload (PostResponse.Payload);
> + if (JsonValue != NULL) {
> + OdataIdValue = JsonObjectGetValue (JsonValueGetObject (JsonValue),
> "@odata.id");
> + if (OdataIdValue != NULL) {
> + OdataIdString = (CHAR8 *)JsonValueGetAsciiString (OdataIdValue);
> + if (OdataIdString != NULL) {
> + *Location = AllocateCopyPool (AsciiStrSize (OdataIdString),
> OdataIdString);
> + }
> + }
> +
> + OdataIdValue = JsonObjectGetValue (JsonValueGetObject (JsonValue),
> "@odata.etag");
> + if (OdataIdValue != NULL) {
> + OdataIdString = (CHAR8 *)JsonValueGetAsciiString (OdataIdValue);
> + if (OdataIdString != NULL) {
> + *Etag = AllocateCopyPool (AsciiStrSize (OdataIdString), OdataIdString);
> + }
> + }
> + }
> + }
> + }
> +
> + //
> + // This is not expected as service does not follow spec.
> + //
> + if (*Location == NULL) {
> + Status = EFI_DEVICE_ERROR;
> + }
> +
> + RedfishFreeResponse (
> + PostResponse.StatusCode,
> + PostResponse.HeaderCount,
> + PostResponse.Headers,
> + PostResponse.Payload
> + );
> +
> + RedfishCleanupPayload (Payload);
> +
> +EXIT_FREE_JSON_VALUE:
> + JsonValueFree (JsonValue);
> + JsonValueFree (ResourceJsonValue);
> +
> + return Status;
> +}
> +
> +/**
> +
> + Find Redfish Resource Config Protocol that supports given schema and
> version.
> +
> + @param[in] Schema Schema name.
> + @param[in] Major Schema version major number.
> + @param[in] Minor Schema version minor number.
> + @param[in] Errata Schema version errata number.
> +
> + @retval EDKII_REDFISH_RESOURCE_CONFIG_PROTOCOL * Pointer to
> protocol
> + @retval NULL No protocol found.
> +
> +**/
> +EDKII_REDFISH_RESOURCE_CONFIG_PROTOCOL *
> +GetRedfishResourceConfigProtocol (
> + IN CHAR8 *Schema,
> + IN CHAR8 *Major,
> + IN CHAR8 *Minor,
> + IN CHAR8 *Errata
> + )
> +{
> + EFI_STATUS Status;
> + EFI_HANDLE *HandleBuffer;
> + UINTN NumberOfHandles;
> + UINTN Index;
> + EDKII_REDFISH_RESOURCE_CONFIG_PROTOCOL *Protocol;
> + REDFISH_SCHEMA_INFO SchemaInfo;
> + BOOLEAN Found;
> +
> + if (IS_EMPTY_STRING (Schema) || IS_EMPTY_STRING (Major) ||
> IS_EMPTY_STRING (Minor) || IS_EMPTY_STRING (Errata)) {
> + return NULL;
> + }
> +
> + Status = gBS->LocateHandleBuffer (
> + ByProtocol,
> + &gEdkIIRedfishResourceConfigProtocolGuid,
> + NULL,
> + &NumberOfHandles,
> + &HandleBuffer
> + );
> + if (EFI_ERROR (Status)) {
> + return NULL;
> + }
> +
> + Found = FALSE;
> +
> + for (Index = 0; Index < NumberOfHandles; Index++) {
> + Status = gBS->HandleProtocol (
> + HandleBuffer[Index],
> + &gEdkIIRedfishResourceConfigProtocolGuid,
> + (VOID **)&Protocol
> + );
> + if (EFI_ERROR (Status)) {
> + continue;
> + }
> +
> + Status = Protocol->GetInfo (Protocol, &SchemaInfo);
> + if (EFI_ERROR (Status)) {
> + continue;
> + }
> +
> + if ((AsciiStrCmp (Schema, SchemaInfo.Schema) == 0) &&
> + (AsciiStrCmp (Major, SchemaInfo.Major) == 0) &&
> + (AsciiStrCmp (Minor, SchemaInfo.Minor) == 0) &&
> + (AsciiStrCmp (Errata, SchemaInfo.Errata) == 0))
> + {
> + Found = TRUE;
> + break;
> + }
> + }
> +
> + FreePool (HandleBuffer);
> +
> + return (Found ? Protocol : NULL);
> +}
> +
> +/**
> +
> + Get supported schema list by given specify schema name.
> +
> + @param[in] Schema Schema type name.
> + @param[out] SchemaInfo Returned schema information.
> +
> + @retval EFI_SUCCESS Schema information is returned successfully.
> + @retval Others Errors occur.
> +
> +**/
> +EFI_STATUS
> +GetSupportedSchemaVersion (
> + IN CHAR8 *Schema,
> + OUT REDFISH_SCHEMA_INFO *SchemaInfo
> + )
> +{
> + EFI_STATUS Status;
> + CHAR8 *SupportSchema;
> + CHAR8 *SchemaName;
> + UINTN Index;
> + UINTN Index2;
> + BOOLEAN Found;
> +
> + if (IS_EMPTY_STRING (Schema) || (SchemaInfo == NULL)) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + Status = RedfishPlatformConfigGetSupportedSchema (NULL,
> &SupportSchema);
> + if (EFI_ERROR (Status)) {
> + return Status;
> + }
> +
> + DEBUG ((DEBUG_INFO, "Supported schema: %a\n", SupportSchema));
> +
> + Index = 0;
> + Found = FALSE;
> + SchemaName = SupportSchema;
> + while (TRUE) {
> + if ((SupportSchema[Index] == ';') || (SupportSchema[Index] == '\0')) {
> + if (AsciiStrnCmp (&SchemaName[SCHEMA_NAME_PREFIX_OFFSET],
> Schema, AsciiStrLen (Schema)) == 0) {
> + Found = TRUE;
> + SupportSchema[Index] = '\0';
> + break;
> + }
> +
> + SchemaName = &SupportSchema[Index + 1];
> + }
> +
> + if (SupportSchema[Index] == '\0') {
> + break;
> + }
> +
> + ++Index;
> + }
> +
> + if (Found) {
> + AsciiStrCpyS (SchemaInfo->Schema, REDFISH_SCHEMA_STRING_SIZE,
> Schema);
> +
> + //
> + // forward to '.'
> + //
> + Index = 0;
> + while (SchemaName[Index] != '\0' && SchemaName[Index] != '.') {
> + ++Index;
> + }
> +
> + ASSERT (SchemaName[Index] != '\0');
> +
> + //
> + // Skip '.' and 'v'
> + //
> + Index += 2;
> +
> + //
> + // forward to '_'
> + //
> + Index2 = Index;
> + while (SchemaName[Index2] != '\0' && SchemaName[Index2] != '_') {
> + ++Index2;
> + }
> +
> + ASSERT (SchemaName[Index2] != '\0');
> +
> + AsciiStrnCpyS (SchemaInfo->Major, REDFISH_SCHEMA_VERSION_SIZE,
> &SchemaName[Index], (Index2 - Index));
> + Index = Index2;
> +
> + //
> + // Skip '_'
> + //
> + ++Index;
> +
> + //
> + // forward to '_'
> + //
> + Index2 = Index;
> + while (SchemaName[Index2] != '\0' && SchemaName[Index2] != '_') {
> + ++Index2;
> + }
> +
> + ASSERT (SchemaName[Index2] != '\0');
> +
> + AsciiStrnCpyS (SchemaInfo->Minor, REDFISH_SCHEMA_VERSION_SIZE,
> &SchemaName[Index], (Index2 - Index));
> + Index = Index2;
> +
> + //
> + // Skip '_'
> + //
> + ++Index;
> +
> + AsciiStrCpyS (SchemaInfo->Errata, REDFISH_SCHEMA_VERSION_SIZE,
> &SchemaName[Index]);
> + }
> +
> + FreePool (SupportSchema);
> +
> + return (Found ? EFI_SUCCESS : EFI_NOT_FOUND);
> +}
> +
> +/**
> +
> + Return system root path. This is dummy function now.
> +
> + @retval NULL Can not find system root path.
> + @retval Other System root path is returned.
> +
> +**/
> +CHAR8 *
> +RedfishGetSystemRootPath (
> + VOID
> + )
> +{
> + return AllocateCopyPool (AsciiStrSize (REDFISH_SYSTEM_ROOT_PATH),
> REDFISH_SYSTEM_ROOT_PATH);
> +}
> +
> +/**
> +
> + Get schema information by given protocol and service instance.
> +
> + @param[in] RedfishService Pointer to Redfish service instance.
> + @param[in] JsonStructProtocol Json Structure protocol instance.
> + @param[in] Uri Target URI.
> + @param[out] SchemaInfo Returned schema information.
> +
> + @retval EFI_SUCCESS Schema information is returned successfully.
> + @retval Others Errors occur.
> +
> +**/
> +EFI_STATUS
> +GetRedfishSchemaInfo (
> + IN REDFISH_SERVICE *RedfishService,
> + IN EFI_REST_JSON_STRUCTURE_PROTOCOL *JsonStructProtocol,
> + IN CHAR8 *Uri,
> + OUT REDFISH_SCHEMA_INFO *SchemaInfo
> + )
> +{
> + EFI_STATUS Status;
> + REDFISH_RESPONSE Response;
> + REDFISH_PAYLOAD Payload;
> + CHAR8 *JsonText;
> + EFI_REST_JSON_STRUCTURE_HEADER *Header;
> +
> + if ((RedfishService == NULL) || (JsonStructProtocol == NULL) ||
> IS_EMPTY_STRING (Uri) || (SchemaInfo == NULL)) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + Status = GetResourceByPath (RedfishService, Uri, &Response);
> + if (EFI_ERROR (Status)) {
> + DEBUG ((DEBUG_ERROR, "%a, failed to get resource from %a %r",
> __FUNCTION__, Uri, Status));
> + return Status;
> + }
> +
> + Payload = Response.Payload;
> + ASSERT (Payload != NULL);
> +
> + JsonText = JsonDumpString (RedfishJsonInPayload (Payload),
> EDKII_JSON_COMPACT);
> + ASSERT (JsonText != NULL);
> +
> + //
> + // Convert JSON text to C structure.
> + //
> + Status = JsonStructProtocol->ToStructure (
> + JsonStructProtocol,
> + NULL,
> + JsonText,
> + &Header
> + );
> + if (EFI_ERROR (Status)) {
> + DEBUG ((DEBUG_ERROR, "%a, ToStructure() failed: %r\n",
> __FUNCTION__, Status));
> + return Status;
> + }
> +
> + AsciiStrCpyS (SchemaInfo->Schema, REDFISH_SCHEMA_STRING_SIZE,
> Header->JsonRsrcIdentifier.NameSpace.ResourceTypeName);
> + AsciiStrCpyS (SchemaInfo->Major, REDFISH_SCHEMA_VERSION_SIZE,
> Header->JsonRsrcIdentifier.NameSpace.MajorVersion);
> + AsciiStrCpyS (SchemaInfo->Minor, REDFISH_SCHEMA_VERSION_SIZE,
> Header->JsonRsrcIdentifier.NameSpace.MinorVersion);
> + AsciiStrCpyS (SchemaInfo->Errata, REDFISH_SCHEMA_VERSION_SIZE,
> Header->JsonRsrcIdentifier.NameSpace.ErrataVersion);
> +
> + //
> + // Release resource.
> + //
> + JsonStructProtocol->DestoryStructure (JsonStructProtocol, Header);
> + FreePool (JsonText);
> + RedfishFreeResponse (Response.StatusCode, Response.HeaderCount,
> Response.Headers, Response.Payload);
> +
> + return EFI_SUCCESS;
> +}
> +
> +/**
> +
> + Get the property name by given Configure Langauge.
> +
> + @param[in] ConfigureLang Configure Language string.
> +
> + @retval EFI_STRING Pointer to property name.
> + @retval NULL There is error.
> +
> +**/
> +EFI_STRING
> +GetPropertyFromConfigureLang (
> + IN EFI_STRING ConfigureLang
> + )
> +{
> + EFI_STRING Property;
> + UINTN Index;
> +
> + if (ConfigureLang == NULL) {
> + return NULL;
> + }
> +
> + Index = 0;
> + Property = ConfigureLang;
> +
> + while (ConfigureLang[Index] != '\0') {
> + if (ConfigureLang[Index] == L'/') {
> + Property = &ConfigureLang[Index];
> + }
> +
> + ++Index;
> + }
> +
> + ++Property;
> +
> + return Property;
> +}
> +
> +/**
> +
> + Get the property value in string type.
> +
> + @param[in] Schema Schema of this property.
> + @param[in] Version Schema version.
> + @param[in] PropertyName Property name.
> + @param[in] ConfigureLang Configure Language of this property.
> +
> + @retval CHAR8* Pointer to the CHAR8 buffer.
> + @retval NULL There is error.
> +
> +**/
> +CHAR8 *
> +GetPropertyStringValue (
> + IN CHAR8 *Schema,
> + IN CHAR8 *Version,
> + IN EFI_STRING PropertyName,
> + IN EFI_STRING ConfigureLang
> + )
> +{
> + EFI_STATUS Status;
> + EDKII_REDFISH_VALUE RedfishValue;
> + EFI_STRING ConfigureLangBuffer;
> + UINTN BufferSize;
> + CHAR8 *AsciiStringValue;
> +
> + if (IS_EMPTY_STRING (Schema) || IS_EMPTY_STRING (Version) ||
> IS_EMPTY_STRING (ConfigureLang) || IS_EMPTY_STRING (PropertyName)) {
> + return NULL;
> + }
> +
> + //
> + // Configure Language buffer.
> + //
> + BufferSize = sizeof (CHAR16) * MAX_CONF_LANG_LEN;
> + ConfigureLangBuffer = AllocatePool (BufferSize);
> + if (ConfigureLangBuffer == NULL) {
> + return NULL;
> + }
> +
> + UnicodeSPrint (ConfigureLangBuffer, BufferSize, L"%s/%s", ConfigureLang,
> PropertyName);
> + Status = RedfishPlatformConfigGetValue (Schema, Version,
> ConfigureLangBuffer, &RedfishValue);
> + if (EFI_ERROR (Status)) {
> + DEBUG ((DEBUG_ERROR, "%a, %a.%a query current setting for %s failed:
> %r\n", __FUNCTION__, Schema, Version, ConfigureLangBuffer, Status));
> + return NULL;
> + }
> +
> + if (RedfishValue.Type != REDFISH_VALUE_TYPE_STRING) {
> + DEBUG ((DEBUG_ERROR, "%a, %a.%a %s value is not string type\n",
> __FUNCTION__, Schema, Version, ConfigureLang));
> + return NULL;
> + }
> +
> + AsciiStringValue = AllocateCopyPool (AsciiStrSize
> (RedfishValue.Value.Buffer), RedfishValue.Value.Buffer);
> + ASSERT (AsciiStringValue != NULL);
> +
> + return AsciiStringValue;
> +}
> +
> +/**
> +
> + Get the property value in numeric type.
> +
> + @param[in] Schema Schema of this property.
> + @param[in] Version Schema version.
> + @param[in] PropertyName Property name.
> + @param[in] ConfigureLang Configure Language of this property.
> +
> + @retval INT64* Pointer to the INT64 value.
> + @retval NULL There is error.
> +
> +**/
> +INT64 *
> +GetPropertyNumericValue (
> + IN CHAR8 *Schema,
> + IN CHAR8 *Version,
> + IN EFI_STRING PropertyName,
> + IN EFI_STRING ConfigureLang
> + )
> +{
> + EFI_STATUS Status;
> + EDKII_REDFISH_VALUE RedfishValue;
> + EFI_STRING ConfigureLangBuffer;
> + UINTN BufferSize;
> + INT64 *ResultValue;
> +
> + if (IS_EMPTY_STRING (Schema) || IS_EMPTY_STRING (Version) ||
> IS_EMPTY_STRING (ConfigureLang) || IS_EMPTY_STRING (PropertyName)) {
> + return NULL;
> + }
> +
> + //
> + // Configure Language buffer.
> + //
> + BufferSize = sizeof (CHAR16) * MAX_CONF_LANG_LEN;
> + ConfigureLangBuffer = AllocatePool (BufferSize);
> + if (ConfigureLangBuffer == NULL) {
> + return NULL;
> + }
> +
> + UnicodeSPrint (ConfigureLangBuffer, BufferSize, L"%s/%s", ConfigureLang,
> PropertyName);
> + Status = RedfishPlatformConfigGetValue (Schema, Version,
> ConfigureLangBuffer, &RedfishValue);
> + if (EFI_ERROR (Status)) {
> + DEBUG ((DEBUG_ERROR, "%a, %a.%a query current setting for %s failed:
> %r\n", __FUNCTION__, Schema, Version, ConfigureLangBuffer, Status));
> + return NULL;
> + }
> +
> + if (RedfishValue.Type != REDFISH_VALUE_TYPE_INTEGER) {
> + DEBUG ((DEBUG_ERROR, "%a, %a.%a %s value is not numeric type\n",
> __FUNCTION__, Schema, Version, ConfigureLang));
> + return NULL;
> + }
> +
> + ResultValue = AllocatePool (sizeof (INT64));
> + ASSERT (ResultValue != NULL);
> + if (ResultValue == NULL) {
> + return NULL;
> + }
> +
> + *ResultValue = RedfishValue.Value.Integer;
> +
> + return ResultValue;
> +}
> +
> +/**
> +
> + Get the property value in Boolean type.
> +
> + @param[in] Schema Schema of this property.
> + @param[in] Version Schema version.
> + @param[in] PropertyName Property name.
> + @param[in] ConfigureLang Configure Language of this property.
> +
> + @retval BOOLEAN Boolean value returned by this property.
> +
> +**/
> +BOOLEAN *
> +GetPropertyBooleanValue (
> + IN CHAR8 *Schema,
> + IN CHAR8 *Version,
> + IN EFI_STRING PropertyName,
> + IN EFI_STRING ConfigureLang
> + )
> +{
> + EFI_STATUS Status;
> + EDKII_REDFISH_VALUE RedfishValue;
> + EFI_STRING ConfigureLangBuffer;
> + UINTN BufferSize;
> + BOOLEAN *ResultValue;
> +
> + if (IS_EMPTY_STRING (Schema) || IS_EMPTY_STRING (Version) ||
> IS_EMPTY_STRING (ConfigureLang) || IS_EMPTY_STRING (PropertyName)) {
> + return NULL;
> + }
> +
> + //
> + // Configure Language buffer.
> + //
> + BufferSize = sizeof (CHAR16) * MAX_CONF_LANG_LEN;
> + ConfigureLangBuffer = AllocatePool (BufferSize);
> + if (ConfigureLangBuffer == NULL) {
> + return NULL;
> + }
> +
> + UnicodeSPrint (ConfigureLangBuffer, BufferSize, L"%s/%s", ConfigureLang,
> PropertyName);
> + Status = RedfishPlatformConfigGetValue (Schema, Version,
> ConfigureLangBuffer, &RedfishValue);
> + if (EFI_ERROR (Status)) {
> + DEBUG ((DEBUG_ERROR, "%a, %a.%a query current setting for %s failed:
> %r\n", __FUNCTION__, Schema, Version, ConfigureLangBuffer, Status));
> + return NULL;
> + }
> +
> + if (RedfishValue.Type != REDFISH_VALUE_TYPE_BOOLEAN) {
> + DEBUG ((DEBUG_ERROR, "%a, %a.%a %s value is not boolean type\n",
> __FUNCTION__, Schema, Version, ConfigureLang));
> + return NULL;
> + }
> +
> + ResultValue = AllocatePool (sizeof (BOOLEAN));
> + ASSERT (ResultValue != NULL);
> + if (ResultValue == NULL) {
> + return NULL;
> + }
> +
> + *ResultValue = RedfishValue.Value.Boolean;
> +
> + return ResultValue;
> +}
> +
> +/**
> +
> + Check and see if we need to do provisioning for this property.
> +
> + @param[in] PropertyBuffer Pointer to property instance.
> + @param[in] ProvisionMode TRUE if we are in provision mode. FALSE
> otherwise.
> +
> + @retval TRUE Provision is required.
> + @retval FALSE Provision is not required.
> +
> +**/
> +BOOLEAN
> +PropertyChecker (
> + IN VOID *PropertyBuffer,
> + IN BOOLEAN ProvisionMode
> + )
> +{
> + if (ProvisionMode && (PropertyBuffer == NULL)) {
> + return TRUE;
> + }
> +
> + if (!ProvisionMode && (PropertyBuffer != NULL)) {
> + return TRUE;
> + }
> +
> + return FALSE;
> +}
> +
> +/**
> +
> + Check and see if we need to do provisioning for this two properties.
> +
> + @param[in] PropertyBuffer1 Pointer to property instance 1.
> + @param[in] PropertyBuffer2 Pointer to property instance 2.
> + @param[in] ProvisionMode TRUE if we are in provision mode. FALSE
> otherwise.
> +
> + @retval TRUE Provision is required.
> + @retval FALSE Provision is not required.
> +
> +**/
> +BOOLEAN
> +PropertyChecker2Parm (
> + IN VOID *PropertyBuffer1,
> + IN VOID *PropertyBuffer2,
> + IN BOOLEAN ProvisionMode
> + )
> +{
> + if (ProvisionMode && ((PropertyBuffer1 == NULL) || (PropertyBuffer2 ==
> NULL))) {
> + return TRUE;
> + }
> +
> + if (!ProvisionMode && (PropertyBuffer1 != NULL) && (PropertyBuffer2 !=
> NULL)) {
> + return TRUE;
> + }
> +
> + return FALSE;
> +}
> +
> +/**
> +
> + Install Boot Maintenance Manager Menu driver.
> +
> + @param[in] ImageHandle The image handle.
> + @param[in] SystemTable The system table.
> +
> + @retval EFI_SUCEESS Install Boot manager menu success.
> + @retval Other Return error status.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +RedfishFeatureUtilityLibConstructor (
> + IN EFI_HANDLE ImageHandle,
> + IN EFI_SYSTEM_TABLE *SystemTable
> + )
> +{
> + return EFI_SUCCESS;
> +}
> +
> +/**
> + Unloads the application and its installed protocol.
> +
> + @param[in] ImageHandle Handle that identifies the image to be
> unloaded.
> + @param[in] SystemTable The system table.
> +
> + @retval EFI_SUCCESS The image has been unloaded.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +RedfishFeatureUtilityLibDestructor (
> + IN EFI_HANDLE ImageHandle,
> + IN EFI_SYSTEM_TABLE *SystemTable
> + )
> +{
> + return EFI_SUCCESS;
> +}
> --
> 2.17.1
prev parent reply other threads:[~2023-05-05 1:15 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-05-04 14:25 [edk2-redfish-client][PATCH 6/8] RedfishClientPkg: Add Redfish Feature Utility library Nickle Wang
2023-05-05 1:15 ` Chang, Abner [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-list from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=MN2PR12MB3966ABBADC4F5F2E23B09A1CEA729@MN2PR12MB3966.namprd12.prod.outlook.com \
--to=devel@edk2.groups.io \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox