From: "Chang, Abner" <abner.chang@amd.com>
To: Nickle Wang <nickle.wang@hpe.com>,
"devel@edk2.groups.io" <devel@edk2.groups.io>
Cc: "Yang, Atom" <Atom.Yang@amd.com>, Nick Ramirez <nramirez@nvidia.com>
Subject: Re: [edk2-staging][PATCH v3 10/15] edk2-staging/RedfishClientPkg: Update Redfish feature utility library
Date: Thu, 28 Jul 2022 03:13:55 +0000 [thread overview]
Message-ID: <MN2PR12MB396684CB6FB8A7D83DAA9026EA969@MN2PR12MB3966.namprd12.prod.outlook.com> (raw)
In-Reply-To: <20220727013802.247-11-nickle.wang@hpe.com>
[AMD Official Use Only - General]
Please search [Chang, Abner] for the comment.
> -----Original Message-----
> From: Nickle Wang <nickle.wang@hpe.com>
> Sent: Wednesday, July 27, 2022 9:38 AM
> To: devel@edk2.groups.io
> Cc: Chang, Abner <Abner.Chang@amd.com>; Yang, Atom
> <Atom.Yang@amd.com>; Nick Ramirez <nramirez@nvidia.com>
> Subject: [edk2-staging][PATCH v3 10/15] edk2-staging/RedfishClientPkg:
> Update Redfish feature utility library
>
> [CAUTION: External Email]
>
> Update Redfish feature utility library in order to support array type
> of resource. Some helper functions are introduced to get Redfish data.
> Also expose RedfishCsCommon.h so that feature utility library can work
> with Redfish C data structure without redundant structure conversion.
>
> Signed-off-by: Nickle Wang <nickle.wang@hpe.com>
> Cc: Abner Chang <abner.chang@amd.com>
> Cc: Yang Atom <Atom.Yang@amd.com>
> Cc: Nick Ramirez <nramirez@nvidia.com>
> ---
> .../Library/RedfishFeatureUtilityLib.h | 756 +++-
> .../RedfishJsonStructure/RedfishCsCommon.h | 14 +
> .../RedfishFeatureUtilityInternal.h | 16 +-
> .../RedfishFeatureUtilityLib.c | 3662 +++++++++++++----
> .../RedfishFeatureUtilityLib.inf | 20 +-
> 5 files changed, 3470 insertions(+), 998 deletions(-)
> create mode 100644
> RedfishClientPkg/Include/RedfishJsonStructure/RedfishCsCommon.h
>
> diff --git a/RedfishClientPkg/Include/Library/RedfishFeatureUtilityLib.h
> b/RedfishClientPkg/Include/Library/RedfishFeatureUtilityLib.h
> index 50ff82c70f..1325976d8c 100644
> --- a/RedfishClientPkg/Include/Library/RedfishFeatureUtilityLib.h
> +++ b/RedfishClientPkg/Include/Library/RedfishFeatureUtilityLib.h
> @@ -1,7 +1,7 @@
> /** @file
> This file defines the Redfish Feature Utility Library interface.
>
> - (C) Copyright 2021 Hewlett Packard Enterprise Development LP<BR>
> + (C) Copyright 2021-2022 Hewlett Packard Enterprise Development LP<BR>
>
> SPDX-License-Identifier: BSD-2-Clause-Patent
>
> @@ -10,8 +10,9 @@
> #ifndef REDFISH_FEATURE_UTILITY_LIB_H_
> #define REDFISH_FEATURE_UTILITY_LIB_H_
>
> -#include <Protocol/EdkIIRedfishResourceConfigProtocol.h>
> -#include <Protocol/RestJsonStructure.h>
> +#include <Library/RedfishLib.h>
> +#include <Protocol/EdkIIRedfishPlatformConfig.h>
> +#include <RedfishJsonStructure/RedfishCsCommon.h>
>
> //
> // Definition of REDFISH_FEATURE_ARRAY_TYPE_CONFIG_LANG
> @@ -31,10 +32,10 @@ typedef struct {
>
> /**
>
> - Read redfish resource by given resource path.
> + Read redfish resource by given resource URI.
>
> @param[in] Service Redfish srvice instacne to make query.
> - @param[in] ResourcePath Target resource path.
> + @param[in] ResourceUri Target resource URI.
> @param[out] Response HTTP response from redfish service.
>
> @retval EFI_SUCCESS Resrouce is returned successfully.
> @@ -42,12 +43,34 @@ typedef struct {
>
> **/
> EFI_STATUS
> -GetResourceByPath (
> +GetResourceByUri (
> IN REDFISH_SERVICE *Service,
> - IN CHAR8 *ResourcePath,
> + IN EFI_STRING ResourceUri,
> OUT REDFISH_RESPONSE *Response
> );
>
> +/**
> +
> + Check if this is the Redpath array. Usually the Redpath array represents
> + the collection member. Return
> +
> + @param[in] ConfigureLang The Redpath to check
> + @param[out] ArraySignatureOpen String to the open of array signature.
> + @param[out] ArraySignatureClose String to the close of array signature.
> +
> + @retval EFI_SUCCESS Index is found.
> + @retval EFI_NOT_FOUND The non-array configure language string is
> retured.
> + @retval EFI_INVALID_PARAMETER The format of input ConfigureLang is
> wrong.
> + @retval Others Errors occur.
> +
> +**/
> +EFI_STATUS
> +IsRedpathArray (
> + IN EFI_STRING ConfigureLang,
> + OUT EFI_STRING *ArraySignatureOpen,
> + OUT EFI_STRING *ArraySignatureClose
> + );
> +
> /**
>
> Search HII database with given Configure Language pattern. Data is handled
> and
> @@ -72,76 +95,142 @@ RedfishFeatureGetUnifiedArrayTypeConfigureLang (
>
> /**
>
> - Get array key by parsing the URI.
> + Clone the configure language list.
>
> - @param[in] Uri URI with array key.
> - @param[out] ArrayKey Array key in given URI string.
> + @param[in] ConfigureLangList The source
> REDFISH_FEATURE_ARRAY_TYPE_CONFIG_LANG_LIST.
> + @param[out] DestConfigureLangList The destination
> REDFISH_FEATURE_ARRAY_TYPE_CONFIG_LANG_LIST.
>
> - @retval EFI_SUCCESS Array key is found.
> - @retval Others Errors occur.
> + @retval EFI_SUCCESS
> REDFISH_FEATURE_ARRAY_TYPE_CONFIG_LANG_LIST is copied.
> + @retval Others Errors occur.
>
> **/
> EFI_STATUS
> -GetArraykeyFromUri (
> - IN CHAR8 *Uri,
> - OUT CHAR8 **ArrayKey
> +CopyConfiglanguageList (
> + IN REDFISH_FEATURE_ARRAY_TYPE_CONFIG_LANG_LIST
> *SourceConfigureLangList,
> + OUT REDFISH_FEATURE_ARRAY_TYPE_CONFIG_LANG_LIST
> *DestConfigureLangList
> );
>
> /**
>
> - Keep configure language with given key in UEFI variable.
> + Get number of node from the string. Node is seperated by '/'.
>
> - @param[in] Schema Schema name.
> - @param[in] Version Schema version.
> - @param[in] Key Key string.
> - @param[in] ConfigureLangIndex Index value.
> + @param[in] NodeString The node string to parse.
>
> - @retval EFI_SUCCESS Data is saved in UEFI variable.
> - @retval Others Errors occur.
> + @retval UINTN Number of nodes in the string.
> +
> +**/
> +UINTN
> +GetNumberOfRedpathNodes (
> + IN EFI_STRING NodeString
> + );
> +
> +/**
> +
> + Get the node string by index
> +
> + @param[in] NodeString The node string to parse.
> + @param[in] Index Index of the node.
> + @param[out] EndOfNodePtr Pointer to receive the poitner to
> + the last character of node string.
> +
> + @retval EFI_STRING the begining of the node string.
> +
> +**/
> +EFI_STRING
> +GetRedpathNodeByIndex (
> + IN EFI_STRING NodeString,
> + IN UINTN Index,
> + OUT EFI_STRING *EndOfNodePtr OPTIONAL
> + );
> +
> +/**
> +
> + 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 EFI_NOT_FOUND The non-array configure language string is
> retured.
> + @retval EFI_INVALID_PARAMETER The format of input ConfigureLang is
> wrong.
> + @retval Others Errors occur.
>
> **/
> EFI_STATUS
> -SetConfigureLangWithkey (
> - IN CHAR8 *Schema,
> - IN CHAR8 *Version,
> - IN CHAR8 *Key,
> - IN UINTN ConfigureLangIndex
> +GetArrayIndexFromArrayTypeConfigureLang (
> + IN CHAR16 *ConfigureLang,
> + OUT CHAR16 **UnifiedConfigureLang,
> + OUT UINTN *Index
> );
>
> /**
>
> - Find configure language with input key string.
> + Clone the configure language list.
> +
> + @param[in] ConfigureLang The pointer to configuration language.
>
> - @param[in] Schema Schema name.
> - @param[in] Version Schema version.
> - @param[in] Property Property name.
> - @param[in] Key Key string.
> + @retval UINTN The index of collection member instance.
> + Value of 0 means no instance is found.
> +**/
> +UINTN
> +ConfiglanguageGetInstanceIndex (
> + IN EFI_STRING ConfigureLang
> + );
>
> - @retval CHAR16 * Corresponding configure langauge
> - @retval NULL No configure language is found
> +/**
> +
> + Destroy the configure language list.
> +
> + @param[in] ConfigureLangList The
> REDFISH_FEATURE_ARRAY_TYPE_CONFIG_LANG_LIST
> + instance to destroy.
> +
> + @retval EFI_SUCCESS
> REDFISH_FEATURE_ARRAY_TYPE_CONFIG_LANG_LIST is copied.
> + @retval Others Errors occur.
>
> **/
> -CHAR16 *
> -GetConfigureLangByKey (
> - IN CHAR8 *Schema,
> - IN CHAR8 *Version,
> - IN CHAR8 *Property,
> - IN CHAR8 *Key
> +EFI_STATUS
> +DestroyConfiglanguageList (
> + IN REDFISH_FEATURE_ARRAY_TYPE_CONFIG_LANG_LIST
> *ConfigureLangList
> );
>
> /**
>
> - Convert HII string value to string value in JSON format.
> + Set the node instance.
>
> - @param[in] HiiStringValue String in HII format.
> + @param[in] DestConfigLang Pointer to the node's configure language
> string.
> + The memory pointed by ConfigLang must be allocated
> + through memory allocation interface. Becasue we will
> replace
> + the pointer in this function.
> + @param[in] MaxtLengthConfigLang The maximum length of ConfigLang.
> + @param[in] ConfigLangInstance Pointer to Collection member instance.
>
> - @retval CHAR8 * String in JSON format.
> - @retval NULL Errors occur.
> + @retval EFI_SUCCESS The instance is inserted to the configure
> language.
> + @retval Others Errors occur.
>
> **/
> -CHAR8 *
> -ConvertHiiStringValueToJsonStringValue (
> - IN EFI_STRING HiiStringValue
> +EFI_STATUS
> +SetResourceConfigLangMemberInstance (
> + IN EFI_STRING *DestConfigLang,
> + IN UINTN MaxtLengthConfigLang,
> + IN REDFISH_FEATURE_ARRAY_TYPE_CONFIG_LANG *ConfigLangInstance
> + );
> +
> +/**
> +
> + 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
> );
>
> /**
> @@ -209,125 +298,157 @@ ApplyFeatureSettingsBooleanType (
>
> /**
>
> - Create HTTP payload and send them to redfish service with POST method.
> + Apply property value to UEFI HII database in vague type.
>
> - @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.
> + @param[in] Schema Property schema.
> + @param[in] Version Property schema version.
> + @param[in] ConfigureLang Configure language refers to this property.
> + @param[in] VagueValuePtr Pointer of vague values to to set.
> + @param[in] NumVagueValues Number of vague values.
>
> - @retval EFI_SUCCESS Data is sent to redfish service successfully.
> + @retval EFI_SUCCESS New value is applied 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
> +ApplyFeatureSettingsVagueType (
> + IN CHAR8 *Schema,
> + IN CHAR8 *Version,
> + IN EFI_STRING ConfigureLang,
> + IN RedfishCS_EmptyProp_KeyValue *VagueValuePtr,
> + IN UINT32 NumberOfVagueValues
> );
>
> /**
>
> - Create HTTP payload and send them to redfish service with PATCH method.
> + Apply property value to UEFI HII database in string array type.
>
> - @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.
> + @param[in] Schema Property schema.
> + @param[in] Version Property schema version.
> + @param[in] ConfigureLang Configure language refers to this property.
> + @param[in] ArrayHead Head of array value.
>
> - @retval EFI_SUCCESS Data is sent to redfish service successfully.
> + @retval EFI_SUCCESS New value is applied successfully.
> @retval Others Errors occur.
>
> **/
> EFI_STATUS
> -CreatePayloadToPatchResource (
> - IN REDFISH_SERVICE *Service,
> - IN REDFISH_PAYLOAD *TargetPayload,
> - IN CHAR8 *Json,
> - OUT CHAR8 **Etag
> +ApplyFeatureSettingsStringArrayType (
> + IN CHAR8 *Schema,
> + IN CHAR8 *Version,
> + IN EFI_STRING ConfigureLang,
> + IN RedfishCS_char_Array *ArrayHead
> );
>
> /**
>
> - Find Redfish Resource Config Protocol that supports given schema and
> version.
> + Apply property value to UEFI HII database in numeric array type (INT64).
>
> - @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.
> + @param[in] Schema Property schema.
> + @param[in] Version Property schema version.
> + @param[in] ConfigureLang Configure language refers to this property.
> + @param[in] ArrayHead Head of array value.
>
> - @retval EDKII_REDFISH_RESOURCE_CONFIG_PROTOCOL * Pointer to
> protocol
> - @retval NULL No protocol found.
> + @retval EFI_SUCCESS New value is applied successfully.
> + @retval Others Errors occur.
>
> **/
> -EDKII_REDFISH_RESOURCE_CONFIG_PROTOCOL *
> -GetRedfishResourceConfigProtocol (
> - IN CHAR8 *Schema,
> - IN CHAR8 *Major,
> - IN CHAR8 *Minor,
> - IN CHAR8 *Errata
> +EFI_STATUS
> +ApplyFeatureSettingsNumericArrayType (
> + IN CHAR8 *Schema,
> + IN CHAR8 *Version,
> + IN EFI_STRING ConfigureLang,
> + IN RedfishCS_int64_Array *ArrayHead
> );
>
> /**
>
> - Get supported schema list by given specify schema name.
> + Apply property value to UEFI HII database in boolean array type (INT64).
>
> - @param[in] Schema Schema type name.
> - @param[out] SchemaInfo Returned schema information.
> + @param[in] Schema Property schema.
> + @param[in] Version Property schema version.
> + @param[in] ConfigureLang Configure language refers to this property.
> + @param[in] ArrayHead Head of Redfich CS boolean array value.
>
> - @retval EFI_SUCCESS Schema information is returned successfully.
> - @retval Others Errors occur.
> + @retval EFI_SUCCESS New value is applied successfully.
> + @retval Others Errors occur.
>
> **/
> EFI_STATUS
> -GetSupportedSchemaVersion (
> - IN CHAR8 *Schema,
> - OUT REDFISH_SCHEMA_INFO *SchemaInfo
> +ApplyFeatureSettingsBooleanArrayType (
> + IN CHAR8 *Schema,
> + IN CHAR8 *Version,
> + IN EFI_STRING ConfigureLang,
> + IN RedfishCS_bool_Array *ArrayHead
> );
>
> /**
>
> - Return system root path
> + 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 NULL Can not find system root path.
> - @retval Other System root path is returned.
> + @retval EFI_SUCCESS Data is sent to redfish service successfully.
> + @retval Others Errors occur.
>
> **/
> -CHAR8 *
> -RedfishGetSystemRootPath (
> - VOID
> +EFI_STATUS
> +CreatePayloadToPostResource (
> + IN REDFISH_SERVICE *Service,
> + IN REDFISH_PAYLOAD *TargetPayload,
> + IN CHAR8 *Json,
> + OUT EFI_STRING *Location,
> + OUT CHAR8 **Etag
> );
>
> /**
>
> - Get schema information by given protocol and service instance.
> + Create HTTP payload and send them to redfish service with PATCH method.
>
> - @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.
> + @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 Schema information is returned successfully.
> - @retval Others Errors occur.
> + @retval EFI_SUCCESS Data is sent to redfish service 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
> +CreatePayloadToPatchResource (
> + IN REDFISH_SERVICE *Service,
> + IN REDFISH_PAYLOAD *TargetPayload,
> + IN CHAR8 *Json,
> + OUT CHAR8 **Etag
> + );
> +
> +/**
> +
> + Save Redfish URI in database for further use.
> +
> + @param[in] ConfigLang ConfigLang to save
> + @param[in] Uri Redfish Uri to save
> +
> + @retval EFI_INVALID_PARAMETR SystemId is NULL or EMPTY
> + @retval EFI_SUCCESS Redfish uri is saved
> +
> +**/
> +EFI_STATUS
> +RedfisSetRedfishUri (
> + IN EFI_STRING ConfigLang,
> + IN EFI_STRING Uri
> );
>
> /**
>
> Get the property name by given Configure Langauge.
>
> - @param[in] ConfigureLang Configure Language string.
> + @param[in] ResourceUri URI of root of resource.
> + @param[in] ConfigureLang Configure Language string.
>
> @retval EFI_STRING Pointer to property name.
> @retval NULL There is error.
> @@ -335,6 +456,7 @@ GetRedfishSchemaInfo (
> **/
> EFI_STRING
> GetPropertyFromConfigureLang (
> + IN EFI_STRING ResourceUri,
> IN EFI_STRING ConfigureLang
> );
>
> @@ -417,25 +539,6 @@ PropertyChecker (
> 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.
> @@ -450,7 +553,7 @@ PropertyChecker2Parm (
> EFI_STATUS
> SetEtagWithUri (
> IN CHAR8 *EtagStr,
> - IN CHAR8 *Uri
> + IN EFI_STRING Uri
> );
>
> /**
> @@ -465,7 +568,396 @@ SetEtagWithUri (
> **/
> CHAR8 *
> GetEtagWithUri (
> - IN CHAR8 *Uri
> + IN EFI_STRING Uri
> + );
> +
> +/**
> +
> + Get @odata.id from give HTTP payload. It's call responsibility to release
> returned buffer.
> +
> + @param[in] Payload HTTP payload
> +
> + @retval NULL Can not find @odata.id from given payload.
> + @retval Others odata.id string is returned.
> +
> +**/
> +EFI_STRING
> +GetOdataId (
> + IN REDFISH_PAYLOAD *Payload
> + );
> +
> +/**
> +
> + Return config language from given URI and prperty name. It's call
> responsibility to release returned buffer.
> +
> + @param[in] Uri The URI to match
> + @param[in] PropertyName The property name of resource. This is
> optional.
> +
> + @retval NULL Can not find redfish uri.
> + @retval Other redfish uri is returned.
> +
> +**/
> +EFI_STRING
> +GetConfigureLang (
> + IN CHAR8 *Uri,
> + IN CHAR8 *PropertyName OPTIONAL
> + );
> +
> +/**
> +
> + Return redfish URI by given config language. It's call responsibility to
> release returned buffer.
> +
> + @param[in] ConfigLang ConfigLang to search.
> +
> + @retval NULL Can not find redfish uri.
> + @retval Other redfish uri is returned.
> +
> +**/
> +EFI_STRING
> +RedfishGetUri (
> + IN EFI_STRING ConfigLang
> + );
> +
> +/**
> +
> + Return config language by given URI. It's call responsibility to release
> returned buffer.
> +
> + @param[in] Uri Uri to search.
> +
> + @retval NULL Can not find redfish uri.
> + @retval Other redfish uri is returned.
> +
> +**/
> +EFI_STRING
> +RedfishGetConfigLanguage (
> + IN EFI_STRING Uri
> + );
> +
> +/**
> +
> + Convert Unicode string to ASCII string. It's call responsibility to release
> returned buffer.
> +
> + @param[in] UnicodeStr Unicode string to convert.
> +
> + @retval CHAR8 * ASCII string returned.
> + @retval NULL Errors occur.
> +
> +**/
> +CHAR8 *
> +StrUnicodeToAscii (
> + IN EFI_STRING UnicodeStr
> + );
> +
> +/**
> +
> + Convert ASCII string to Unicode string. It's call responsibility to release
> returned buffer.
> +
> + @param[in] AsciiStr ASCII string to convert.
> +
> + @retval EFI_STRING Unicode string returned.
> + @retval NULL Errors occur.
> +
> +**/
> +EFI_STRING
> +StrAsciiToUnicode (
> + IN CHAR8 *AsciiStr
> + );
> +
> +/**
> +
> + Check and see if ETAG is identical to what we keep in system.
> +
> + @param[in] Uri URI requested
> + @param[in] EtagInHeader ETAG string returned from HTTP request.
> + @param[in] EtagInJson ETAG string in JSON body.
> +
> + @retval TRUE ETAG is identical.
> + @retval FALSE ETAG is changed.
> +
> +**/
> +BOOLEAN
> +CheckEtag (
> + IN EFI_STRING Uri,
> + IN CHAR8 *EtagInHeader,
> + IN CHAR8 *EtagInJson
> + );
> +
> +/**
> +
> + Get the property string value in array 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.
> + @param[out] ArraySize The size of returned array.
> +
> + @retval CHAR8 ** Returned string array. NULL while error happens.
> +
> +**/
> +CHAR8 **
> +GetPropertyStringArrayValue (
> + IN CHAR8 *Schema,
> + IN CHAR8 *Version,
> + IN EFI_STRING PropertyName,
> + IN EFI_STRING ConfigureLang,
> + OUT UINTN *ArraySize
> + );
> +
> +/**
> +
> + Get the property numeric value in array 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.
> + @param[out] ArraySize The size of returned array.
> +
> + @retval INT64 ** Returned integer array. NULL while error happens.
> +
> +**/
> +INT64 *
> +GetPropertyNumericArrayValue (
> + IN CHAR8 *Schema,
> + IN CHAR8 *Version,
> + IN EFI_STRING PropertyName,
> + IN EFI_STRING ConfigureLang,
> + OUT UINTN *ArraySize
> + );
> +
> +/**
> +
> + Get the property boolean value in array 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.
> + @param[out] ArraySize The size of returned array.
> +
> + @retval BOOLEAN * Returned boolean array. NULL while error
> happens.
> +
> +**/
> +BOOLEAN *
> +GetPropertyBooleanArrayValue (
> + IN CHAR8 *Schema,
> + IN CHAR8 *Version,
> + IN EFI_STRING PropertyName,
> + IN EFI_STRING ConfigureLang,
> + OUT UINTN *ArraySize
> + );
> +
> +/**
> +
> + Get the property value in the vague 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.
> + @param[out] NumberOfValues Return the number of vague type of
> values
> +
> + @retval RedfishCS_EmptyProp_KeyValue The pointer to the structure
> + of vague type of values.
> +
> +**/
> +RedfishCS_EmptyProp_KeyValue *
> +GetPropertyVagueValue (
> + IN CHAR8 *Schema,
> + IN CHAR8 *Version,
> + IN EFI_STRING PropertyName,
> + IN EFI_STRING ConfigureLang,
> + OUT UINT32 *NumberOfValues
> + );
> +
> +/**
> +
> + Free the list of empty property key values.
> +
> + @param[in] EmptyPropKeyValueListHead The head of
> RedfishCS_EmptyProp_KeyValue
> +
> +**/
> +VOID
> +FreeEmptyPropKeyValueList (
> + RedfishCS_EmptyProp_KeyValue *EmptyPropKeyValueListHead
> + );
> +
> +/**
> +
> + Check and see if given property is in JSON context or not
> +
> + @param[in] Property Property name string
> + @param[in] Json The JSON context to search.
> +
> + @retval TRUE Property is found in JSON context
> + @retval FALSE Property is not in JSON context
> +
> +**/
> +BOOLEAN
> +MatchPropertyWithJsonContext (
> + IN EFI_STRING Property,
> + IN CHAR8 *Json
> +);
> +
> +/**
> +
> + Create string array and append to arry node in Redfish JSON convert
> format.
> +
> + @param[in,out] Head The head of string array.
> + @param[in] StringArray Input string array.
> + @param[in] ArraySize The size of StringArray.
> +
> + @retval EFI_SUCCESS String array is created successfully.
> + @retval Others Error happens
> +
> +**/
> +EFI_STATUS
> +AddRedfishCharArray (
> + IN OUT RedfishCS_char_Array **Head,
> + IN CHAR8 **StringArray,
> + IN UINTN ArraySize
> + );
> +
> +/**
> +
> + Create numeric array and append to arry node in Redfish JSON convert
> format.
> +
> + @param[in,out] Head The head of string array.
> + @param[in] NumericArray Input numeric array.
> + @param[in] ArraySize The size of StringArray.
> +
> + @retval EFI_SUCCESS String array is created successfully.
> + @retval Others Error happens
> +
> +**/
> +EFI_STATUS
> +AddRedfishNumericArray (
> + IN OUT RedfishCS_int64_Array **Head,
> + IN INT64 *NumericArray,
> + IN UINTN ArraySize
> + );
> +
> +/**
> +
> + Create boolean array and append to arry node in Redfish JSON convert
> format.
> +
> + @param[in,out] Head The head of string array.
> + @param[in] BooleanArray Input boolean array.
> + @param[in] ArraySize The size of BooleanArray.
> +
> + @retval EFI_SUCCESS String array is created successfully.
> + @retval Others Error happens
> +
> +**/
> +EFI_STATUS
> +AddRedfishBooleanArray (
> + IN OUT RedfishCS_bool_Array **Head,
> + IN BOOLEAN *BooleanArray,
> + IN UINTN ArraySize
> + );
> +/**
> +
> + Check and see if value in Redfish string array are all the same as the one
> + from HII configuration.
> +
> + @param[in] Head The head of string array.
> + @param[in] StringArray Input string array.
> + @param[in] ArraySize The size of StringArray.
> +
> + @retval TRUE All string in Redfish array are as same as string
> + in HII configuration array.
> + FALSE These two array are not identical.
> +
> +**/
> +BOOLEAN
> +CompareRedfishStringArrayValues (
> + IN RedfishCS_char_Array *Head,
> + IN CHAR8 **StringArray,
> + IN UINTN ArraySize
> + );
> +
> +/**
> +
> + Check and see if value in Redfish numeric array are all the same as the one
> + from HII configuration.
> +
> + @param[in] Head The head of Redfish CS numeraic array.
> + @param[in] NumericArray Input numeric array.
> + @param[in] ArraySize The size of NumericArray.
> +
> + @retval TRUE All string in Redfish array are as same as integer
> + in HII configuration array.
> + FALSE These two array are not identical.
> +
> +**/
> +BOOLEAN
> +CompareRedfishNumericArrayValues (
> + IN RedfishCS_int64_Array *Head,
> + IN INT64 *NumericArray,
> + IN UINTN ArraySize
> + );
> +
> +/**
> +
> + Check and see if value in Redfish boolean array are all the same as the one
> + from HII configuration.
> +
> + @param[in] Head The head of Redfish CS boolean array.
> + @param[in] BooleanArray Input boolean array.
> + @param[in] ArraySize The size of BooleanArray.
> +
> + @retval TRUE All string in Redfish array are as same as integer
> + in HII configuration array.
> + FALSE These two array are not identical.
> +
> +**/
> +BOOLEAN
> +CompareRedfishBooleanArrayValues (
> + IN RedfishCS_bool_Array *Head,
> + IN BOOLEAN *BooleanArray,
> + IN UINTN ArraySize
> + );
> +
> +/**
> +
> + Check and see if any difference between two vague value set.
> + This is just a simple check.
> +
> + @param[in] RedfishVagueKeyValuePtr The vague key value sets on
> Redfish service.
> + @param[in] RedfishVagueKeyValueNumber The numebr of vague key
> value sets
> + @param[in] ConfigVagueKeyValuePtr The vague configuration on
> platform.
> + @param[in] ConfigVagueKeyValueNumber The numebr of vague key
> value sets
> +
> + @retval TRUE All values are the same.
> + FALSE There is some difference.
> +
> +**/
> +BOOLEAN
> +CompareRedfishPropertyVagueValues (
> + IN RedfishCS_EmptyProp_KeyValue *RedfishVagueKeyValuePtr,
> + IN UINT32 RedfishVagueKeyValueNumber,
> + IN RedfishCS_EmptyProp_KeyValue *ConfigVagueKeyValuePtr,
> + IN UINT32 ConfigVagueKeyValueNumber
> + );
> +
> +/**
> +
> + Find "ETag" and "Location" from either HTTP header or Redfish response.
> +
> + @param[in] Response HTTP response
> + @param[out] Etag String buffer to return ETag
> + @param[out] Location String buffer to return Location
> +
> + @retval EFI_SUCCESS Data is found and returned.
> + @retval Others Errors occur.
> +
> +**/
> +EFI_STATUS
> +GetEtagAndLocation (
> + IN REDFISH_RESPONSE *Response,
> + OUT CHAR8 **Etag, OPTIONAL
> + OUT EFI_STRING *Location OPTIONAL
> );
>
> #endif
> diff --git
> a/RedfishClientPkg/Include/RedfishJsonStructure/RedfishCsCommon.h
> b/RedfishClientPkg/Include/RedfishJsonStructure/RedfishCsCommon.h
> new file mode 100644
> index 0000000000..4d0ae50fc8
> --- /dev/null
> +++ b/RedfishClientPkg/Include/RedfishJsonStructure/RedfishCsCommon.h
> @@ -0,0 +1,14 @@
> +/** @file
> + Wrapper file for RedfishCsCommon.h
> +
> + (C) Copyright 2021-2022 Hewlett Packard Enterprise Development LP<BR>
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef WRAPPER_REDFISH_CS_COMMON_H_
> +#define WRAPPER_REDFISH_CS_COMMON_H_
> +
> +#include "ConverterLib/include/RedfishCsCommon.h"
> +
> +#endif
> diff --git
> a/RedfishClientPkg/Library/RedfishFeatureUtilityLib/RedfishFeatureUtilityInt
> ernal.h
> b/RedfishClientPkg/Library/RedfishFeatureUtilityLib/RedfishFeatureUtilityInt
> ernal.h
> index 7d38d327ef..38d2af52b2 100644
> ---
> a/RedfishClientPkg/Library/RedfishFeatureUtilityLib/RedfishFeatureUtilityInt
> ernal.h
> +++
> b/RedfishClientPkg/Library/RedfishFeatureUtilityLib/RedfishFeatureUtilityInt
> ernal.h
> @@ -1,7 +1,7 @@
> /** @file
> Common header file for RedfishFeatureUtilityLib driver.
>
> - (C) Copyright 2020-2021 Hewlett Packard Enterprise Development LP<BR>
> + (C) Copyright 2020-2022 Hewlett Packard Enterprise Development LP<BR>
>
> SPDX-License-Identifier: BSD-2-Clause-Patent
>
> @@ -11,33 +11,39 @@
> #define REDFISH_FEATURE_INTERNAL_H_
>
> #include <Uefi.h>
> +#include <RedfishBase.h>
> +
> +#include <IndustryStandard/Http11.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 <Library/PrintLib.h>
> +#include <Library/HttpLib.h>
>
> #include <Guid/VariableFormat.h>
>
> #include <Protocol/EdkIIRedfishETagProtocol.h>
> +#include <Protocol/EdkIIRedfishConfigLangMapProtocol.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 "x-uefi-redfish-"
> #define SCHEMA_NAME_PREFIX_OFFSET (AsciiStrLen
> (SCHEMA_NAME_PREFIX))
> -#define REDFISH_SYSTEM_ROOT_PATH "/v1/Systems[UUID~%g]"
> +#define REDFISH_ROOT_PATH "/v1"
> +#define REDFISH_ROOT_PATH_UNICODE L"/v1"
> #define MAX_CONF_LANG_LEN 128
> +#define MAX_REDFISH_URL_LEN 255
> +#define REGULAR_EXPRESSION_ARRAY L"\\[.*\\]/.*"
>
> #define BIOS_CONFIG_TO_REDFISH_REDPATH_ARRAY_START_SIGNATURE
> L"{"
> #define BIOS_CONFIG_TO_REDFISH_REDPATH_ARRAY_END_SIGNATURE
> L"}"
> diff --git
> a/RedfishClientPkg/Library/RedfishFeatureUtilityLib/RedfishFeatureUtilityLib
> .c
> b/RedfishClientPkg/Library/RedfishFeatureUtilityLib/RedfishFeatureUtilityLib
> .c
> index cf8696e5f0..2bd7f58f9c 100644
> ---
> a/RedfishClientPkg/Library/RedfishFeatureUtilityLib/RedfishFeatureUtilityLib
> .c
> +++
> b/RedfishClientPkg/Library/RedfishFeatureUtilityLib/RedfishFeatureUtilityLib
> .c
> @@ -1,7 +1,7 @@
> /** @file
> Redfish feature utility library implementation
>
> - (C) Copyright 2020-2021 Hewlett Packard Enterprise Development LP<BR>
> + (C) Copyright 2020-2022 Hewlett Packard Enterprise Development LP<BR>
>
> SPDX-License-Identifier: BSD-2-Clause-Patent
>
> @@ -9,7 +9,34 @@
>
> #include "RedfishFeatureUtilityInternal.h"
>
> -EDKII_REDFISH_ETAG_PROTOCOL *mEtagProtocol;
> +EDKII_REDFISH_ETAG_PROTOCOL *mEtagProtocol = NULL;
> +EDKII_REDFISH_CONFIG_LANG_MAP_PROTOCOL
> *mConfigLangMapProtocol = NULL;
> +
> +
> +EFI_STATUS
> +RedfishLocateProtocol (
[Chang, Abner]
The function header is missed.
Abner
> + IN VOID **ProtocolInstance,
> + IN EFI_GUID *ProtocolGuid
> + )
> +{
> + EFI_STATUS Status;
> +
> + if (ProtocolInstance == NULL || ProtocolGuid == NULL) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + if (*ProtocolInstance != NULL) {
> + return EFI_SUCCESS;
> + }
> +
> + Status = gBS->LocateProtocol (
> + ProtocolGuid,
> + NULL,
> + ProtocolInstance
> + );
> + return Status;
> +}
> +
>
> /**
>
> @@ -71,227 +98,168 @@ GetArraykeyFromUri (
>
> /**
>
> - Keep configure language with given key in UEFI variable.
> + Keep ETAG string and URI string in database.
>
> - @param[in] Schema Schema name.
> - @param[in] Version Schema version.
> - @param[in] Key Key string.
> - @param[in] ConfigureLangIndex Index value.
> + @param[in] EtagStr ETAG string.
> + @param[in] Uri URI string.
>
> - @retval EFI_SUCCESS Data is saved in UEFI variable.
> - @retval Others Errors occur.
> + @retval EFI_SUCCESS ETAG and URI are applied successfully.
> + @retval Others Errors occur.
>
> **/
> EFI_STATUS
> -SetConfigureLangWithkey (
> - IN CHAR8 *Schema,
> - IN CHAR8 *Version,
> - IN CHAR8 *Key,
> - IN UINTN ConfigureLangIndex
> +SetEtagWithUri (
> + IN CHAR8 *EtagStr,
> + IN EFI_STRING Uri
> )
> {
> - CHAR16 IndexString[INDEX_STRING_SIZE];
> - CHAR16 VarName[INDEX_VARIABLE_SIZE];
> - CHAR16 *VarData;
> - EFI_STATUS Status;
> - //
> - // Variable content.
> - //
> - UnicodeSPrint (IndexString, sizeof (IndexString), INDEX_STRING,
> ConfigureLangIndex);
> + EFI_STATUS Status;
> + CHAR8 *AsciiUri;
>
> - //
> - // Variable name.
> - //
> - UnicodeSPrint (VarName, sizeof (VarName), L"%a_%a_%a", Schema,
> Version, Key);
> + if (IS_EMPTY_STRING (EtagStr) || IS_EMPTY_STRING (Uri)) {
> + return EFI_INVALID_PARAMETER;
> + }
>
> - //
> - // 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);
> + Status = RedfishLocateProtocol ((VOID **)&mEtagProtocol,
> &gEdkIIRedfishETagProtocolGuid);
> + if (EFI_ERROR (Status)) {
> + DEBUG ((DEBUG_ERROR, "%a, fail to locate
> gEdkIIRedfishETagProtocolGuid: %r\n", __FUNCTION__, Status));
> + return Status;
> }
>
> - return gRT->SetVariable (VarName, &gEfiCallerIdGuid,
> VARIABLE_ATTRIBUTE_NV_BS, StrSize (IndexString), (VOID *)&IndexString);
> + AsciiUri = StrUnicodeToAscii (Uri);
> + if (AsciiUri == NULL) {
> + return EFI_OUT_OF_RESOURCES;
> + }
> +
> + mEtagProtocol->Set (mEtagProtocol, AsciiUri, EtagStr);
> + mEtagProtocol->Flush (mEtagProtocol);
> +
> + FreePool (AsciiUri);
> +
> + return EFI_SUCCESS;
> }
>
> /**
>
> - Find configure language with input key string.
> + Find ETAG string that refers to given URI.
>
> - @param[in] Schema Schema name.
> - @param[in] Version Schema version.
> - @param[in] Property Property name.
> - @param[in] Key Key string.
> + @param[in] Uri Target URI string.
>
> - @retval CHAR16 * Corresponding configure langauge
> - @retval NULL No configure language is found
> + @retval CHAR8 * ETAG string
> + @retval NULL No ETAG is found.
>
> **/
> -CHAR16 *
> -GetConfigureLangByKey (
> - IN CHAR8 *Schema,
> - IN CHAR8 *Version,
> - IN CHAR8 *Property, OPTIONAL
> - IN CHAR8 *Key
> +CHAR8 *
> +GetEtagWithUri (
> + IN EFI_STRING Uri
> )
> {
> - EFI_STATUS Status;
> - CHAR16 VariableName[64];
> - UINTN VariableSize;
> - CHAR16 *CollectionIndex;
> - CHAR16 *ConfigureLang;
> - UINTN ConfigureLangLen;
> + EFI_STATUS Status;
> + CHAR8 *AsciiUri;
> + CHAR8 *EtagStr;
>
> - if (Schema == NULL || Version == NULL || Key == NULL) {
> + if (IS_EMPTY_STRING (Uri)) {
> return NULL;
> }
>
> - CollectionIndex = NULL;
> - ConfigureLang = NULL;
> -
> - UnicodeSPrint (VariableName, 64, L"%a_%a_%a", Schema, Version, Key);
> -
> - Status = GetVariable2 (
> - VariableName,
> - &gEfiCallerIdGuid,
> - (VOID *)&CollectionIndex,
> - &VariableSize
> - );
> + Status = RedfishLocateProtocol ((VOID **)&mEtagProtocol,
> &gEdkIIRedfishETagProtocolGuid);
> if (EFI_ERROR (Status)) {
> + DEBUG ((DEBUG_ERROR, "%a, fail to locate
> gEdkIIRedfishETagProtocolGuid: %r\n", __FUNCTION__, 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);
> + AsciiUri = StrUnicodeToAscii (Uri);
> + if (AsciiUri == NULL) {
> + return NULL;
> }
>
> - 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;
> + Status = mEtagProtocol->Get (mEtagProtocol, AsciiUri, &EtagStr);
>
> - if (IS_EMPTY_STRING (EtagStr) || IS_EMPTY_STRING (Uri)) {
> - return EFI_INVALID_PARAMETER;
> - }
> + FreePool (AsciiUri);
>
> - if (mEtagProtocol == NULL) {
> - Status = gBS->LocateProtocol (
> - &gEdkIIRedfishETagProtocolGuid,
> - NULL,
> - (VOID **)&mEtagProtocol
> - );
> - if (EFI_ERROR (Status)) {
> - return Status;
> - }
> + if (EFI_ERROR (Status)) {
> + return NULL;
> }
>
> - mEtagProtocol->Set (mEtagProtocol, Uri, EtagStr);
> - mEtagProtocol->Flush (mEtagProtocol);
> -
> - return EFI_SUCCESS;
> + return EtagStr;
> }
>
> /**
>
> - Find ETAG string that refers to given URI.
> + Convert Unicode string to ASCII string. It's call responsibility to release
> returned buffer.
>
> - @param[in] Uri Target URI string.
> + @param[in] UnicodeStr Unicode string to convert.
>
> - @retval CHAR8 * ETAG string
> - @retval NULL No ETAG is found.
> + @retval CHAR8 * ASCII string returned.
> + @retval NULL Errors occur.
>
> **/
> CHAR8 *
> -GetEtagWithUri (
> - IN CHAR8 *Uri
> +StrUnicodeToAscii (
> + IN EFI_STRING UnicodeStr
> )
> {
> - EFI_STATUS Status;
> - CHAR8 *EtagStr;
> + CHAR8 *AsciiStr;
> + UINTN AsciiStrSize;
> + EFI_STATUS Status;
>
> - if (IS_EMPTY_STRING (Uri)) {
> + if (IS_EMPTY_STRING (UnicodeStr)) {
> return NULL;
> }
>
> - if (mEtagProtocol == NULL) {
> - Status = gBS->LocateProtocol (
> - &gEdkIIRedfishETagProtocolGuid,
> - NULL,
> - (VOID **)&mEtagProtocol
> - );
> - if (EFI_ERROR (Status)) {
> - return NULL;
> - }
> + AsciiStrSize = StrLen (UnicodeStr) + 1;
> + AsciiStr = AllocatePool (AsciiStrSize);
> + if (AsciiStr == NULL) {
> + return NULL;
> }
>
> - Status = mEtagProtocol->Get (mEtagProtocol, Uri, &EtagStr);
> + Status = UnicodeStrToAsciiStrS (UnicodeStr, AsciiStr, AsciiStrSize);
> if (EFI_ERROR (Status)) {
> + DEBUG ((DEBUG_ERROR, "UnicodeStrToAsciiStrS failed: %r\n", Status));
> + FreePool (AsciiStr);
> return NULL;
> }
>
> - return EtagStr;
> + return AsciiStr;
> }
>
> /**
>
> - Convert HII string value to string value in JSON format.
> + Convert ASCII string to Unicode string. It's call responsibility to release
> returned buffer.
>
> - @param[in] HiiStringValue String in HII format.
> + @param[in] AsciiStr ASCII string to convert.
>
> - @retval CHAR8 * String in JSON format.
> + @retval EFI_STRING Unicode string returned.
> @retval NULL Errors occur.
>
> **/
> -CHAR8 *
> -ConvertHiiStringValueToJsonStringValue (
> - IN EFI_STRING HiiStringValue
> +EFI_STRING
> +StrAsciiToUnicode (
> + IN CHAR8 *AsciiStr
> )
> {
> - CHAR8 *JsonValue;
> - UINTN JsonValueSize;
> + EFI_STRING UnicodeStr;
> + UINTN UnicodeStrSize;
> + EFI_STATUS Status;
>
> - if (IS_EMPTY_STRING (HiiStringValue)) {
> + if (IS_EMPTY_STRING (AsciiStr)) {
> return NULL;
> }
>
> - JsonValueSize = StrLen (HiiStringValue) + 1;
> - JsonValue = AllocatePool (JsonValueSize);
> - UnicodeStrToAsciiStrS (HiiStringValue, JsonValue, JsonValueSize);
> + UnicodeStrSize = (AsciiStrLen (AsciiStr) + 1) * sizeof (CHAR16);
> + UnicodeStr = AllocatePool (UnicodeStrSize);
> + if (UnicodeStr == NULL) {
> + return NULL;
> + }
> +
> + Status = AsciiStrToUnicodeStrS (AsciiStr, UnicodeStr, UnicodeStrSize);
> + if (EFI_ERROR (Status)) {
> + DEBUG ((DEBUG_ERROR, "t failed: %r\n", Status));
> + FreePool (UnicodeStr);
> + return NULL;
> + }
>
> - return JsonValue;
> + return UnicodeStr;
> }
>
> /**
> @@ -480,997 +448,2979 @@ ApplyFeatureSettingsBooleanType (
>
> /**
>
> - Read redfish resource by given resource path.
> + Apply property value to UEFI HII database in vague type.
>
> - @param[in] Service Redfish srvice instacne to make query.
> - @param[in] ResourcePath Target resource path.
> - @param[out] Response HTTP response from redfish service.
> + @param[in] Schema Property schema.
> + @param[in] Version Property schema version.
> + @param[in] ConfigureLang Configure language refers to this property.
> + @param[in] VagueValuePtr Pointer of vague values to to set.
> + @param[in] NumVagueValues Number of vague values.
>
> - @retval EFI_SUCCESS Resrouce is returned successfully.
> + @retval EFI_SUCCESS New value is applied successfully.
> @retval Others Errors occur.
>
> **/
> EFI_STATUS
> -GetResourceByPath (
> - IN REDFISH_SERVICE *Service,
> - IN CHAR8 *ResourcePath,
> - OUT REDFISH_RESPONSE *Response
> +ApplyFeatureSettingsVagueType (
> + IN CHAR8 *Schema,
> + IN CHAR8 *Version,
> + IN EFI_STRING ConfigureLang,
> + IN RedfishCS_EmptyProp_KeyValue *VagueValuePtr,
> + IN UINT32 NumberOfVagueValues
> )
> {
> - EFI_STATUS Status;
> -
> - if (Service == NULL || Response == NULL || IS_EMPTY_STRING
> (ResourcePath)) {
> + EFI_STATUS Status;
> + UINTN StrSize;
> + CHAR8 *ConfigureLangAscii;
> + CHAR8 *ConfigureLangKeyAscii;
> + EFI_STRING ConfigureKeyLang;
> + EDKII_REDFISH_VALUE RedfishValue;
> + EDKII_REDFISH_VALUE_TYPES PropertyDatatype;
> + RedfishCS_EmptyProp_KeyValue *CurrentVagueValuePtr;
> +
> + if (IS_EMPTY_STRING (Schema) || IS_EMPTY_STRING (Version) ||
> IS_EMPTY_STRING (ConfigureLang) || VagueValuePtr == NULL ||
> NumberOfVagueValues == 0) {
> return EFI_INVALID_PARAMETER;
> }
>
> - //
> - // Get resource from redfish service.
> - //
> - Status = RedfishGetByService (
> - Service,
> - ResourcePath,
> - Response
> - );
> + ConfigureLangAscii = AllocatePool (StrLen (ConfigureLang) + 1);
> + if (ConfigureLangAscii == NULL) {
> + Status = EFI_OUT_OF_RESOURCES;
> + DEBUG ((DEBUG_ERROR, "%a, Allocate memory for generate
> ConfigureLang of vague key of %a.%a %s failed: %r\n", __FUNCTION__,
> Schema, Version, ConfigureLang, Status));
> + return Status;
> + }
> + Status = UnicodeStrToAsciiStrS (ConfigureLang, ConfigureLangAscii, StrLen
> (ConfigureLang) + 1);
> 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;
> - }
> -
> + DEBUG ((DEBUG_ERROR, "%a, Convert the configureLang of vague key of
> %a.%a %s failed: %r\n", __FUNCTION__, Schema, Version, ConfigureLang,
> Status));
> return Status;
> }
>
> + CurrentVagueValuePtr = VagueValuePtr;
> + while (CurrentVagueValuePtr != NULL) {
> + //
> + // Generate ConfigureLang with the key name
> + //
> + //ConfigureKeyLang = GetConfigureLang (ConfigureLangAscii,
> CurrentVagueValuePtr->KeyNamePtr);
> + StrSize = AsciiStrLen (ConfigureLangAscii) + AsciiStrLen
> (CurrentVagueValuePtr->KeyNamePtr) + 2;
> + ConfigureLangKeyAscii = AllocateZeroPool (StrSize);
> + ConfigureKeyLang = AllocateZeroPool (StrSize * sizeof (CHAR16));
> + if (ConfigureLangKeyAscii == NULL || ConfigureKeyLang == NULL) {
> + DEBUG ((DEBUG_ERROR, "%a, Generate ConfigureLang of vague key of
> %a.%a %s %a failed!\n", __FUNCTION__, Schema, Version, ConfigureLang,
> CurrentVagueValuePtr->KeyNamePtr));
> + goto ErrorContinue;
> + }
> + AsciiStrCatS(ConfigureLangKeyAscii, StrSize, ConfigureLangAscii);
> + AsciiStrCatS(ConfigureLangKeyAscii, StrSize, "/");
> + AsciiStrCatS(ConfigureLangKeyAscii, StrSize, CurrentVagueValuePtr-
> >KeyNamePtr);
> + AsciiStrToUnicodeStrS(ConfigureLangKeyAscii, ConfigureKeyLang, StrSize);
> + FreePool (ConfigureLangKeyAscii);
> + ConfigureLangKeyAscii = NULL;
> + //
> + // Initial property data type and value.
> + //
> + if (CurrentVagueValuePtr->Value->DataType ==
> RedfishCS_Vague_DataType_String) {
> + PropertyDatatype = REDFISH_VALUE_TYPE_STRING;
> + } else if (CurrentVagueValuePtr->Value->DataType ==
> RedfishCS_Vague_DataType_Bool) {
> + PropertyDatatype = REDFISH_VALUE_TYPE_BOOLEAN;
> + } else if (CurrentVagueValuePtr->Value->DataType ==
> RedfishCS_Vague_DataType_Int64) {
> + PropertyDatatype = REDFISH_VALUE_TYPE_INTEGER;
> + } else {
> + DEBUG((DEBUG_ERROR, "%a, %a.%a %s Unsupported Redfish property
> data type\n", __FUNCTION__, Schema, Version, ConfigureLang));
> + goto ErrorContinue;
> + }
> +
> + //
> + // Get the current value from HII
> + //
> + Status = RedfishPlatformConfigGetValue (Schema, Version,
> ConfigureKeyLang, &RedfishValue);
> + if (EFI_ERROR (Status)) {
> + DEBUG ((DEBUG_ERROR, "%a, %a.%a %s failed: %r\n", __FUNCTION__,
> Schema, Version, ConfigureKeyLang, Status));
> + } else {
> + if (RedfishValue.Type != PropertyDatatype) {
> + DEBUG((DEBUG_ERROR, "%a, %a.%a %s mismatched data type\n",
> __FUNCTION__, Schema, Version, ConfigureKeyLang));
> + goto ErrorContinue;
> + }
> + if (PropertyDatatype == REDFISH_VALUE_TYPE_STRING) {
> + //
> + // This is a string property.
> + //
> + if (AsciiStrCmp (CurrentVagueValuePtr->Value->DataValue.CharPtr,
> RedfishValue.Value.Buffer) != 0) {
> + //
> + // Apply settings from redfish
> + //
> + DEBUG ((DEBUG_INFO, "%a, %a.%a apply %s from %a to %a\n",
> __FUNCTION__, Schema, Version, ConfigureKeyLang,
> RedfishValue.Value.Buffer, CurrentVagueValuePtr->Value-
> >DataValue.CharPtr));
> + FreePool (RedfishValue.Value.Buffer);
> + RedfishValue.Value.Buffer = CurrentVagueValuePtr->Value-
> >DataValue.CharPtr;
> + Status = RedfishPlatformConfigSetValue (Schema, Version,
> ConfigureKeyLang, RedfishValue);
> + if (EFI_ERROR (Status)) {
> + DEBUG ((DEBUG_ERROR, "%a, apply %a to %a failed: %r\n",
> __FUNCTION__, ConfigureKeyLang, CurrentVagueValuePtr->Value-
> >DataValue.CharPtr, Status));
> + }
> + } else {
> + DEBUG ((DEBUG_INFO, "%a, %a.%a %s value is: %a\n",
> __FUNCTION__, Schema, Version, ConfigureKeyLang,
> RedfishValue.Value.Buffer, Status));
> + }
> + } else if (PropertyDatatype == REDFISH_VALUE_TYPE_BOOLEAN) {
> + //
> + // This is a boolean property.
> + //
> + if (RedfishValue.Value.Boolean != *CurrentVagueValuePtr->Value-
> >DataValue.BoolPtr) {
> + //
> + // Apply settings from redfish
> + //
> + DEBUG ((DEBUG_INFO, "%a, %a.%a apply %s from %a to %a\n",
> + __FUNCTION__,
> + Schema,
> + Version,
> + ConfigureKeyLang,
> + (RedfishValue.Value.Boolean ? "True" : "False"),
> + (*CurrentVagueValuePtr->Value->DataValue.BoolPtr ? "True" :
> "False")));
> +
> + RedfishValue.Value.Boolean = (BOOLEAN)*CurrentVagueValuePtr-
> >Value->DataValue.BoolPtr;
> + Status = RedfishPlatformConfigSetValue (Schema, Version,
> ConfigureKeyLang, RedfishValue);
> + if (EFI_ERROR (Status)) {
> + DEBUG ((DEBUG_ERROR, "%a, apply %s to %a failed: %r\n",
> __FUNCTION__, ConfigureKeyLang, (*CurrentVagueValuePtr->Value-
> >DataValue.BoolPtr ? "True" : "False"), Status));
> + }
> + } else {
> + DEBUG ((DEBUG_INFO, "%a, %a.%a %s value is: %a\n",
> __FUNCTION__, Schema, Version, ConfigureKeyLang,
> (RedfishValue.Value.Boolean ? "True" : "False"), Status));
> + }
> + } else if (PropertyDatatype == REDFISH_VALUE_TYPE_INTEGER) {
> + //
> + // This is a integer property.
> + //
> + if (RedfishValue.Value.Integer != *CurrentVagueValuePtr->Value-
> >DataValue.Int64Ptr) {
> + //
> + // Apply settings from redfish
> + //
> + DEBUG ((DEBUG_INFO, "%a, %a.%a apply %s from 0x%x to 0x%x\n",
> __FUNCTION__, Schema, Version, ConfigureKeyLang,
> RedfishValue.Value.Integer, *CurrentVagueValuePtr->Value-
> >DataValue.Int64Ptr));
> +
> + RedfishValue.Value.Integer = (INT64)*CurrentVagueValuePtr->Value-
> >DataValue.Int64Ptr;
> + Status = RedfishPlatformConfigSetValue (Schema, Version,
> ConfigureKeyLang, RedfishValue);
> + if (EFI_ERROR (Status)) {
> + DEBUG ((DEBUG_ERROR, "%a, apply %s to 0x%x failed: %r\n",
> __FUNCTION__, ConfigureKeyLang, *CurrentVagueValuePtr->Value-
> >DataValue.Int64Ptr, Status));
> + }
> + } else {
> + DEBUG ((DEBUG_INFO, "%a, %a.%a %s value is: 0x%x\n",
> __FUNCTION__, Schema, Version, ConfigureKeyLang,
> RedfishValue.Value.Integer, Status));
> + }
> + } else {
> + DEBUG((DEBUG_ERROR, "%a, %a.%a %s Unsupported Redfish property
> data type\n", __FUNCTION__, Schema, Version, ConfigureLang));
> + goto ErrorContinue;
> + }
> + }
> +
> +ErrorContinue:;
> + if (ConfigureLangKeyAscii != NULL) {
> + FreePool (ConfigureLangKeyAscii);
> + ConfigureLangKeyAscii = NULL;
> + }
> + if (ConfigureKeyLang != NULL) {
> + FreePool (ConfigureKeyLang);
> + ConfigureKeyLang = NULL;
> + }
> + CurrentVagueValuePtr = CurrentVagueValuePtr->NextKeyValuePtr;
> + };
> +
> + if (ConfigureLangAscii != NULL) {
> + FreePool (ConfigureLangAscii);
> + }
> + if (ConfigureLangKeyAscii != NULL) {
> + FreePool (ConfigureLangKeyAscii);
> + }
> + if (ConfigureKeyLang != NULL) {
> + FreePool (ConfigureKeyLang);
> + }
> 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.
> + Release the memory in RedfishValue while value type is array.
>
> - @retval EFI_SUCCESS Index is found.
> - @retval Others Errors occur.
> + @param[in] RedfishValue Pointer to Redfish value
>
> **/
> -EFI_STATUS
> -GetArrayIndexFromArrayTypeConfigureLang (
> - IN CHAR16 *ConfigureLang,
> - OUT CHAR16 **UnifiedConfigureLang,
> - OUT UINTN *Index
> +VOID
> +FreeArrayTypeRedfishValue (
> + EDKII_REDFISH_VALUE *RedfishValue
> )
> {
> - 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;
> - }
> + UINTN Index;
>
> - //
> - // looking for index signature "{""
> - //
> - IndexString = StrStr (TmpConfigureLang,
> BIOS_CONFIG_TO_REDFISH_REDPATH_ARRAY_START_SIGNATURE);
> - if (IndexString == NULL) {
> - return EFI_NOT_FOUND;
> + if (RedfishValue == NULL) {
> + return;
> }
>
> - //
> - // 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;
> + if (RedfishValue->Type != REDFISH_VALUE_TYPE_INTEGER_ARRAY &&
> RedfishValue->Type != REDFISH_VALUE_TYPE_STRING_ARRAY) {
> + return;
> }
>
> - //
> - // Append '\0' for converting decimal string to integer.
> - //
> - TmpString[0] = '\0';
> + switch (RedfishValue->Type) {
> + case REDFISH_VALUE_TYPE_STRING_ARRAY:
> + for (Index = 0; Index < RedfishValue->ArrayCount; Index++) {
> + FreePool (RedfishValue->Value.StringArray[Index]);
> + }
> + FreePool (RedfishValue->Value.StringArray);
> + RedfishValue->Value.StringArray = NULL;
> + break;
>
> - //
> - // Convert decimal string to integer
> - //
> - *Index = StrDecimalToUintn (IndexString + StrLen
> (BIOS_CONFIG_TO_REDFISH_REDPATH_ARRAY_START_SIGNATURE));
> + case REDFISH_VALUE_TYPE_INTEGER_ARRAY:
> + FreePool (RedfishValue->Value.IntegerArray);
> + RedfishValue->Value.IntegerArray = NULL;
> + break;
>
> - //
> - // Resotre the '}' character and remove rest of string.
> - //
> - TmpString[0] = L'}';
> - TmpString[1] = '\0';
> + case REDFISH_VALUE_TYPE_BOOLEAN_ARRAY:
> + FreePool (RedfishValue->Value.BooleanArray);
> + RedfishValue->Value.BooleanArray = NULL;
> + break;
>
> - *UnifiedConfigureLang = TmpConfigureLang;
> + default:
> + return;
> + }
>
> - return EFI_SUCCESS;
> + RedfishValue->ArrayCount = 0;
> }
>
> +
> /**
>
> - Search HII database with given Configure Language pattern. Data is handled
> and
> - returned in array.
> + Apply property value to UEFI HII database in string array type.
>
> - @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.
> + @param[in] Schema Property schema.
> + @param[in] Version Property schema version.
> + @param[in] ConfigureLang Configure language refers to this property.
> + @param[in] ArrayHead Head of array value.
>
> - @retval EFI_SUCCESS Data is found and returned.
> + @retval EFI_SUCCESS New value is applied successfully.
> @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
> +ApplyFeatureSettingsStringArrayType (
> + IN CHAR8 *Schema,
> + IN CHAR8 *Version,
> + IN EFI_STRING ConfigureLang,
> + IN RedfishCS_char_Array *ArrayHead
> )
> {
> - 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];
> + EFI_STATUS Status;
> + EDKII_REDFISH_VALUE RedfishValue;
> + UINTN Index;
> + RedfishCS_char_Array *Buffer;
>
> - if (IS_EMPTY_STRING (Schema) || IS_EMPTY_STRING (Version) ||
> UnifiedConfigureLangList == NULL) {
> + if (IS_EMPTY_STRING (Schema) || IS_EMPTY_STRING (Version) ||
> IS_EMPTY_STRING (ConfigureLang) || ArrayHead == NULL) {
> return EFI_INVALID_PARAMETER;
> }
>
> - UnifiedConfigureLangList->Count = 0;
> - UnifiedConfigureLangList->List = NULL;
> - ZeroMem (UnifiedConfigureLangPool, sizeof (UnifiedConfigureLangPool));
> -
> - Status = RedfishPlatformConfigGetConfigureLang (Schema, Version,
> Pattern, &ConfigureLangList, &Count);
> + //
> + // Get the current value from HII
> + //
> + Status = RedfishPlatformConfigGetValue (Schema, Version, ConfigureLang,
> &RedfishValue);
> if (EFI_ERROR (Status)) {
> - DEBUG ((DEBUG_ERROR, "%a, RedfishFeatureGetConfigureLangRegex
> failed: %r\n", __FUNCTION__, Status));
> - return Status;
> - }
> + DEBUG ((DEBUG_ERROR, "%a, %a.%a %s failed: %r\n", __FUNCTION__,
> Schema, Version, ConfigureLang, Status));
> + } else {
>
> - if (Count == 0) {
> - return EFI_NOT_FOUND;
> + if (RedfishValue.Type != REDFISH_VALUE_TYPE_STRING_ARRAY) {
> + DEBUG ((DEBUG_ERROR, "%a, %a.%a %s value is not string array
> type\n", __FUNCTION__, Schema, Version, ConfigureLang));
> + return EFI_DEVICE_ERROR;
> + }
> +
> + //
> + // If there is no change in array, do nothing
> + //
> + if (!CompareRedfishStringArrayValues (ArrayHead,
> RedfishValue.Value.StringArray, RedfishValue.ArrayCount)) {
> + //
> + // Apply settings from redfish
> + //
> + DEBUG ((DEBUG_INFO, "%a, %a.%a apply %s for array\n",
> __FUNCTION__, Schema, Version, ConfigureLang));
> + FreeArrayTypeRedfishValue (&RedfishValue);
> +
> + //
> + // Convert array from RedfishCS_char_Array to EDKII_REDFISH_VALUE
> + //
> + RedfishValue.ArrayCount = 0;
> + Buffer = ArrayHead;
> + while (Buffer != NULL) {
> + RedfishValue.ArrayCount += 1;
> + Buffer = Buffer->Next;
> + }
> +
> + //
> + // Allocate pool for new values
> + //
> + RedfishValue.Value.StringArray = AllocatePool
> (RedfishValue.ArrayCount *sizeof (CHAR8 *));
> + if (RedfishValue.Value.StringArray == NULL) {
> + ASSERT (FALSE);
> + return EFI_OUT_OF_RESOURCES;
> + }
> +
> + Buffer = ArrayHead;
> + Index = 0;
> + while (Buffer != NULL) {
> + RedfishValue.Value.StringArray[Index] = AllocateCopyPool (AsciiStrSize
> (Buffer->ArrayValue), Buffer->ArrayValue);
> + if (RedfishValue.Value.StringArray[Index] == NULL) {
> + ASSERT (FALSE);
> + return EFI_OUT_OF_RESOURCES;
> + }
> + Buffer = Buffer->Next;
> + Index++;
> + }
> +
> + ASSERT (Index <= RedfishValue.ArrayCount);
> +
> + Status = RedfishPlatformConfigSetValue (Schema, Version,
> ConfigureLang, RedfishValue);
> + if (EFI_ERROR (Status)) {
> + DEBUG ((DEBUG_ERROR, "%a, apply %s array failed: %r\n",
> __FUNCTION__, ConfigureLang, Status));
> + }
> + } else {
> + DEBUG ((DEBUG_ERROR, "%a, %a.%a %s array value has no change\n",
> __FUNCTION__, Schema, Version, ConfigureLang));
> + }
> }
>
> - for (Index = 0; Index < Count; Index++) {
> - Status = GetArrayIndexFromArrayTypeConfigureLang
> (ConfigureLangList[Index], &UnifiedConfigureLang, &ArrayIndex);
> - if (EFI_ERROR (Status)) {
> - ASSERT (FALSE);
> - continue;
> + return Status;
> +}
> +
> +/**
> +
> + Apply property value to UEFI HII database in numeric array type (INT64).
> +
> + @param[in] Schema Property schema.
> + @param[in] Version Property schema version.
> + @param[in] ConfigureLang Configure language refers to this property.
> + @param[in] ArrayHead Head of array value.
> +
> + @retval EFI_SUCCESS New value is applied successfully.
> + @retval Others Errors occur.
> +
> +**/
> +EFI_STATUS
> +ApplyFeatureSettingsNumericArrayType (
> + IN CHAR8 *Schema,
> + IN CHAR8 *Version,
> + IN EFI_STRING ConfigureLang,
> + IN RedfishCS_int64_Array *ArrayHead
> + )
> +{
> + EFI_STATUS Status;
> + EDKII_REDFISH_VALUE RedfishValue;
> + UINTN Index;
> + RedfishCS_int64_Array *Buffer;
> +
> + if (IS_EMPTY_STRING (Schema) || IS_EMPTY_STRING (Version) ||
> IS_EMPTY_STRING (ConfigureLang) || ArrayHead == 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_INTEGER_ARRAY) {
> + DEBUG ((DEBUG_ERROR, "%a, %a.%a %s value is not string array type\n",
> __FUNCTION__, Schema, Version, ConfigureLang));
> + return EFI_DEVICE_ERROR;
> }
>
> //
> - // Check if this configure language is duplicated.
> + // If there is no change in array, do nothing
> //
> - Duplicated = FALSE;
> - for (Index2 = 0; Index2 <
> BIOS_CONFIG_TO_REDFISH_REDPATH_POOL_SIZE; Index2++) {
> - if (UnifiedConfigureLangPool[Index2].ConfigureLang == NULL) {
> - break;
> + if (!CompareRedfishNumericArrayValues (ArrayHead,
> RedfishValue.Value.IntegerArray, RedfishValue.ArrayCount)) {
> + //
> + // Apply settings from redfish
> + //
> + DEBUG ((DEBUG_INFO, "%a, %a.%a apply %s for array\n",
> __FUNCTION__, Schema, Version, ConfigureLang));
> + FreeArrayTypeRedfishValue (&RedfishValue);
> +
> + //
> + // Convert array from RedfishCS_int64_Array to EDKII_REDFISH_VALUE
> + //
> + RedfishValue.ArrayCount = 0;
> + Buffer = ArrayHead;
> + while (Buffer != NULL) {
> + RedfishValue.ArrayCount += 1;
> + Buffer = Buffer->Next;
> + }
> +
> + //
> + // Allocate pool for new values
> + //
> + RedfishValue.Value.IntegerArray = AllocatePool
> (RedfishValue.ArrayCount * sizeof (INT64));
> + if (RedfishValue.Value.IntegerArray == NULL) {
> + ASSERT (FALSE);
> + return EFI_OUT_OF_RESOURCES;
> + }
> +
> + Buffer = ArrayHead;
> + Index = 0;
> + while (Buffer != NULL) {
> + RedfishValue.Value.IntegerArray[Index] = (INT64)*Buffer->ArrayValue;
> + Buffer = Buffer->Next;
> + Index++;
> + }
> +
> + ASSERT (Index <= RedfishValue.ArrayCount);
> +
> + Status = RedfishPlatformConfigSetValue (Schema, Version,
> ConfigureLang, RedfishValue);
> + if (EFI_ERROR (Status)) {
> + DEBUG ((DEBUG_ERROR, "%a, apply %s array failed: %r\n",
> __FUNCTION__, ConfigureLang, Status));
> + }
> + } else {
> + DEBUG ((DEBUG_ERROR, "%a, %a.%a %s array value has no change\n",
> __FUNCTION__, Schema, Version, ConfigureLang));
> + }
> + }
> +
> + return Status;
> +}
> +
> +/**
> +
> + Apply property value to UEFI HII database in boolean array type (INT64).
> +
> + @param[in] Schema Property schema.
> + @param[in] Version Property schema version.
> + @param[in] ConfigureLang Configure language refers to this property.
> + @param[in] ArrayHead Head of Redfich CS boolean array value.
> +
> + @retval EFI_SUCCESS New value is applied successfully.
> + @retval Others Errors occur.
> +
> +**/
> +EFI_STATUS
> +ApplyFeatureSettingsBooleanArrayType (
> + IN CHAR8 *Schema,
> + IN CHAR8 *Version,
> + IN EFI_STRING ConfigureLang,
> + IN RedfishCS_bool_Array *ArrayHead
> + )
> +{
> + EFI_STATUS Status;
> + EDKII_REDFISH_VALUE RedfishValue;
> + UINTN Index;
> + RedfishCS_bool_Array *Buffer;
> +
> + if (IS_EMPTY_STRING (Schema) || IS_EMPTY_STRING (Version) ||
> IS_EMPTY_STRING (ConfigureLang) || ArrayHead == 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_BOOLEAN_ARRAY) {
> + DEBUG ((DEBUG_ERROR, "%a, %a.%a %s value is not string array type\n",
> __FUNCTION__, Schema, Version, ConfigureLang));
> + return EFI_DEVICE_ERROR;
> + }
> +
> + //
> + // If there is no change in array, do nothing
> + //
> + if (!CompareRedfishBooleanArrayValues (ArrayHead,
> RedfishValue.Value.BooleanArray, RedfishValue.ArrayCount)) {
> + //
> + // Apply settings from redfish
> + //
> + DEBUG ((DEBUG_INFO, "%a, %a.%a apply %s for array\n",
> __FUNCTION__, Schema, Version, ConfigureLang));
> + FreeArrayTypeRedfishValue (&RedfishValue);
> +
> + //
> + // Convert array from RedfishCS_int64_Array to EDKII_REDFISH_VALUE
> + //
> + RedfishValue.ArrayCount = 0;
> + Buffer = ArrayHead;
> + while (Buffer != NULL) {
> + RedfishValue.ArrayCount += 1;
> + Buffer = Buffer->Next;
> + }
> +
> + //
> + // Allocate pool for new values
> + //
> + RedfishValue.Value.BooleanArray = AllocatePool
> (RedfishValue.ArrayCount * sizeof (BOOLEAN));
> + if (RedfishValue.Value.BooleanArray == NULL) {
> + ASSERT (FALSE);
> + return EFI_OUT_OF_RESOURCES;
> + }
> +
> + Buffer = ArrayHead;
> + Index = 0;
> + while (Buffer != NULL) {
> + RedfishValue.Value.BooleanArray[Index] = (BOOLEAN)*Buffer-
> >ArrayValue;
> + Buffer = Buffer->Next;
> + Index++;
> + }
> +
> + ASSERT (Index <= RedfishValue.ArrayCount);
> +
> + Status = RedfishPlatformConfigSetValue (Schema, Version,
> ConfigureLang, RedfishValue);
> + if (EFI_ERROR (Status)) {
> + DEBUG ((DEBUG_ERROR, "%a, apply %s array failed: %r\n",
> __FUNCTION__, ConfigureLang, Status));
> + }
> + } else {
> + DEBUG ((DEBUG_ERROR, "%a, %a.%a %s array value has no change\n",
> __FUNCTION__, Schema, Version, ConfigureLang));
> + }
> + }
> +
> + return Status;
> +}
> +
> +/**
> +
> + Read redfish resource by given resource URI.
> +
> + @param[in] Service Redfish srvice instacne to make query.
> + @param[in] ResourceUri Target resource URI.
> + @param[out] Response HTTP response from redfish service.
> +
> + @retval EFI_SUCCESS Resrouce is returned successfully.
> + @retval Others Errors occur.
> +
> +**/
> +EFI_STATUS
> +GetResourceByUri (
> + IN REDFISH_SERVICE *Service,
> + IN EFI_STRING ResourceUri,
> + OUT REDFISH_RESPONSE *Response
> + )
> +{
> + EFI_STATUS Status;
> + CHAR8 *AsciiResourceUri;
> +
> + if (Service == NULL || Response == NULL || IS_EMPTY_STRING
> (ResourceUri)) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + AsciiResourceUri = StrUnicodeToAscii (ResourceUri);
> + if (AsciiResourceUri == NULL) {
> + return EFI_OUT_OF_RESOURCES;
> + }
> +
> + //
> + // Get resource from redfish service.
> + //
> + Status = RedfishGetByUri (
> + Service,
> + AsciiResourceUri,
> + Response
> + );
> + if (EFI_ERROR (Status)) {
> + DEBUG ((DEBUG_ERROR, "%a, RedfishGetByUri to %a failed: %r\n",
> __FUNCTION__, AsciiResourceUri, Status));
> + if (Response->Payload != NULL) {
> + RedfishDumpPayload (Response->Payload);
> + RedfishFreeResponse (
> + NULL,
> + 0,
> + NULL,
> + Response->Payload
> + );
> + Response->Payload = NULL;
> + }
> + }
> +
> + if (AsciiResourceUri != NULL) {
> + FreePool (AsciiResourceUri);
> + }
> +
> + return Status;
> +}
> +
> +/**
> +
> + Check if this is the Redpath array. Usually the Redpath array represents
> + the collection member. Return
> +
> + @param[in] ConfigureLang The Redpath to check
> + @param[out] ArraySignatureOpen String to the open of array signature.
> + @param[out] ArraySignatureClose String to the close of array signature.
> +
> + @retval EFI_SUCCESS Index is found.
> + @retval EFI_NOT_FOUND The non-array configure language string is
> retured.
> + @retval EFI_INVALID_PARAMETER The format of input ConfigureLang is
> wrong.
> + @retval Others Errors occur.
> +
> +**/
> +EFI_STATUS
> +IsRedpathArray (
> + IN EFI_STRING ConfigureLang,
> + OUT EFI_STRING *ArraySignatureOpen OPTIONAL,
> + OUT EFI_STRING *ArraySignatureClose OPTIONAL
> + )
> +{
> + CHAR16 *IndexString;
> +
> + if (ConfigureLang == NULL) {
> + return EFI_INVALID_PARAMETER;
> + }
> + if (ArraySignatureOpen != NULL) {
> + *ArraySignatureOpen = NULL;
> + }
> + if (ArraySignatureClose != NULL) {
> + *ArraySignatureClose = NULL;
> + }
> +
> + //
> + // looking for index signature "{""
> + //
> + IndexString = StrStr (ConfigureLang,
> BIOS_CONFIG_TO_REDFISH_REDPATH_ARRAY_START_SIGNATURE);
> + if (IndexString != NULL) {
> + if (ArraySignatureOpen != NULL) {
> + *ArraySignatureOpen = IndexString;
> + }
> + //
> + // Skip "{"
> + //
> + IndexString = IndexString + StrLen
> (BIOS_CONFIG_TO_REDFISH_REDPATH_ARRAY_START_SIGNATURE);
> + //
> + // Looking for "}"
> + //
> + IndexString = StrStr (IndexString,
> BIOS_CONFIG_TO_REDFISH_REDPATH_ARRAY_END_SIGNATURE);
> + if (IndexString == NULL) {
> + return EFI_INVALID_PARAMETER;
> + }
> + if (ArraySignatureClose != NULL) {
> + *ArraySignatureClose = IndexString;
> + }
> + return EFI_SUCCESS;
> + }
> + return EFI_NOT_FOUND;
> +}
> +
> +/**
> +
> + Get number of node from the string. Node is seperated by '/'.
> +
> + @param[in] NodeString The node string to parse.
> +
> + @retval UINTN Number of nodes in the string.
> +
> +**/
> +UINTN
> +GetNumberOfRedpathNodes (
> + IN EFI_STRING NodeString
> + )
> +{
> + UINTN Index;
> + UINTN NumberNodes;
> + UINTN StringLen;
> +
> + NumberNodes = 0;
> + StringLen = StrLen (NodeString);
> + Index = 1; // ConfigLang always starts with '/'.
> + while (Index < StringLen) {
> + if (*(NodeString + Index) == L'/') {
> + NumberNodes ++;
> + }
> + Index ++;
> + };
> + NumberNodes ++;
> +
> + return (NumberNodes);
> +}
> +
> +/**
> +
> + Get the node string by index
> +
> + @param[in] NodeString The node string to parse.
> + @param[in] Index Zero-based index of the node.
> + @param[out] EndOfNodePtr Pointer to receive the poitner to
> + the last character of node string.
> +
> + @retval EFI_STRING the begining of the node string.
> +
> +**/
> +EFI_STRING
> +GetRedpathNodeByIndex (
> + IN EFI_STRING NodeString,
> + IN UINTN Index,
> + OUT EFI_STRING *EndOfNodePtr OPTIONAL
> + )
> +{
> + UINTN NumberNodes;
> + UINTN StringLen;
> + UINTN StringIndex;
> + EFI_STRING NodeStart;
> + EFI_STRING NodeEnd;
> +
> + NumberNodes = 0;
> + StringLen = StrLen (NodeString);
> + StringIndex = 1; // ConfigLang always starts with '/'.
> + NodeStart = NodeString;
> + if (EndOfNodePtr != NULL) {
> + *EndOfNodePtr = NULL;
> + }
> + while (StringIndex < StringLen) {
> + if (*(NodeString + StringIndex) == L'/') {
> + NodeEnd = NodeString + StringIndex - 1;
> + if (NumberNodes == Index) {
> + if (EndOfNodePtr != NULL) {
> + *EndOfNodePtr = NodeEnd;
> + }
> + return NodeStart;
> + } else {
> + NodeStart = NodeString + StringIndex + 1;
> }
> + }
> + StringIndex ++;
> + };
> + return (NULL);
> +}
> +
> +/**
> +
> + 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 EFI_NOT_FOUND The non-array configure language string is
> retured.
> + @retval EFI_INVALID_PARAMETER The format of input ConfigureLang is
> wrong.
> + @retval Others Errors occur.
> +
> +**/
> +EFI_STATUS
> +GetArrayIndexFromArrayTypeConfigureLang (
> + IN CHAR16 *ConfigureLang,
> + OUT CHAR16 **UnifiedConfigureLang,
> + OUT UINTN *Index
> + )
> +{
> + EFI_STATUS Status;
> + CHAR16 *TmpConfigureLang;
> + CHAR16 *ArrayOpenStr;
> + CHAR16 *ArrayCloseStr;
> + INTN StringIndex;
> +
> + if (ConfigureLang == NULL || UnifiedConfigureLang == NULL || Index ==
> NULL) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + TmpConfigureLang = AllocateCopyPool (StrSize (ConfigureLang),
> ConfigureLang);
> + if (TmpConfigureLang == NULL) {
> + return EFI_OUT_OF_RESOURCES;
> + }
> +
> + Status = IsRedpathArray (TmpConfigureLang, &ArrayOpenStr,
> &ArrayCloseStr);
> + if (!EFI_ERROR (Status)) {
> + //
> + // Append '\0' for converting decimal string to integer.
> + //
> + ArrayCloseStr[0] = '\0';
> +
> + //
> + // Convert decimal string to integer
> + //
> + *Index = StrDecimalToUintn (ArrayOpenStr + StrLen
> (BIOS_CONFIG_TO_REDFISH_REDPATH_ARRAY_START_SIGNATURE));
> +
> + //
> + // Resotre the '}' character and remove rest of string.
> + //
> + ArrayCloseStr[0] = L'}';
> + ArrayCloseStr[1] = '\0';
> + *UnifiedConfigureLang = TmpConfigureLang;
> + } else {
> + if (Status == EFI_NOT_FOUND) {
> + //
> + // This is not the redpath array. Search "/" for the parent root.
> + //
> + *Index = 0;
> + StringIndex = StrLen (TmpConfigureLang) - 1;
> + while (StringIndex >= 0 && *(TmpConfigureLang + StringIndex) != '/') {
> + StringIndex --;
> + };
> + if (StringIndex >= 0 ) {
> + *(TmpConfigureLang + StringIndex) = '\0';
> + *UnifiedConfigureLang = TmpConfigureLang;
> + Status = EFI_SUCCESS;
> + } else {
> + Status = EFI_INVALID_PARAMETER;
> + }
> + }
> + }
> + return Status;
> +}
> +
> +/**
> +
> + Clone the configure language list.
> +
> + @param[in] ConfigureLangList The source
> REDFISH_FEATURE_ARRAY_TYPE_CONFIG_LANG_LIST.
> + @param[out] DestConfigureLangList The destination
> REDFISH_FEATURE_ARRAY_TYPE_CONFIG_LANG_LIST.
> +
> + @retval EFI_SUCCESS
> REDFISH_FEATURE_ARRAY_TYPE_CONFIG_LANG_LIST is copied.
> + @retval Others Errors occur.
> +
> +**/
> +EFI_STATUS
> +CopyConfiglanguageList (
> + IN REDFISH_FEATURE_ARRAY_TYPE_CONFIG_LANG_LIST
> *SourceConfigureLangList,
> + OUT REDFISH_FEATURE_ARRAY_TYPE_CONFIG_LANG_LIST
> *DestConfigureLangList
> + )
> +{
> + UINTN Index;
> +
> + if (SourceConfigureLangList == NULL || DestConfigureLangList == NULL) {
> + return EFI_INVALID_PARAMETER;
> + }
> + DestConfigureLangList->Count = SourceConfigureLangList->Count;
> + DestConfigureLangList->List =
> + (REDFISH_FEATURE_ARRAY_TYPE_CONFIG_LANG *)AllocateZeroPool
> (sizeof (REDFISH_FEATURE_ARRAY_TYPE_CONFIG_LANG) *
> DestConfigureLangList->Count);
> + if (DestConfigureLangList->List == NULL) {
> + DEBUG ((DEBUG_ERROR, "%a, Fail to allocate memory for
> REDFISH_FEATURE_ARRAY_TYPE_CONFIG_LANG.\n", __FUNCTION__));
> + return EFI_OUT_OF_RESOURCES;
> + }
> + for (Index = 0; Index < SourceConfigureLangList->Count; Index++) {
> + DestConfigureLangList->List [Index].Index = SourceConfigureLangList-
> >List[Index].Index;
> + DestConfigureLangList->List [Index].ConfigureLang =
> + (EFI_STRING)AllocateCopyPool(StrSize(SourceConfigureLangList-
> >List[Index].ConfigureLang), (VOID *)SourceConfigureLangList-
> >List[Index].ConfigureLang);
> + }
> + return EFI_SUCCESS;
> +}
> +
> +/**
> +
> + Clone the configure language list.
> +
> + @param[in] ConfigureLang The pointer to configuration language.
> +
> + @retval UINTN The index of collection member instance.
> + Value of 0 means no instance is found.
> +**/
> +UINTN
> +ConfiglanguageGetInstanceIndex (
> + IN EFI_STRING ConfigureLang
> + )
> +{
> + INTN LeftBracketIndex;
> + INTN RightBracketIndex;
> + INTN Index;
> + UINT64 Instance;
> + EFI_STATUS Status;
> +
> + if (ConfigureLang == NULL) {
> + return 0;
> + }
> + LeftBracketIndex = 0;
> + RightBracketIndex = 0;
> + Index = StrLen (ConfigureLang) - 1;
> + while (Index >= 0) {
> + if (*(ConfigureLang + Index) == L'{') {
> + LeftBracketIndex = Index;
> + break;
> + }
> + if (*(ConfigureLang + Index) == L'}') {
> + RightBracketIndex = Index;
> + }
> + Index --;
> + };
> + if ((RightBracketIndex - LeftBracketIndex) <= 1) {
> + return 0;
> + }
> + *(ConfigureLang + RightBracketIndex) = 0;
> + Status = StrDecimalToUint64S (ConfigureLang + LeftBracketIndex + 1, NULL,
> &Instance);
> + if (EFI_ERROR(Status)) {
> + Instance = 0;
> + }
> + //
> + // Restore right curly bracket.
> + //
> + *(ConfigureLang + RightBracketIndex) = L'}';
> + return (UINTN)Instance;
> +}
> +
> +/**
> +
> + Destroy the configure language list.
> +
> + @param[in] ConfigureLangList The
> REDFISH_FEATURE_ARRAY_TYPE_CONFIG_LANG_LIST
> + instance to destroy.
> +
> + @retval EFI_SUCCESS
> REDFISH_FEATURE_ARRAY_TYPE_CONFIG_LANG_LIST is copied.
> + @retval Others Errors occur.
> +
> +**/
> +EFI_STATUS
> +DestroyConfiglanguageList (
> + IN REDFISH_FEATURE_ARRAY_TYPE_CONFIG_LANG_LIST
> *ConfigureLangList
> + )
> +{
> + UINTN Index;
> +
> + if (ConfigureLangList == NULL) {
> + return EFI_INVALID_PARAMETER;
> + }
> + if (ConfigureLangList->List != NULL) {
> + for (Index = 0; Index < ConfigureLangList->Count; Index++) {
> + if (ConfigureLangList->List [Index].ConfigureLang != NULL) {
> + FreePool (ConfigureLangList->List [Index].ConfigureLang);
> + }
> + }
> + FreePool (ConfigureLangList->List);
> + ConfigureLangList->List = NULL;
> + }
> +
> + return EFI_SUCCESS;
> +}
> +
> +/**
> +
> + Set the node instance.
> +
> + @param[in] DestConfigLang Pointer to the node's configure language
> string.
> + The memory pointed by ConfigLang must be allocated
> + through memory allocation interface. Becasue we will
> replace
> + the pointer in this function.
> + @param[in] MaxtLengthConfigLang The maximum length of ConfigLang.
> + @param[in] ConfigLangInstance Pointer to Collection member instance.
> +
> + @retval EFI_SUCCESS The instance is inserted to the configure
> language.
> + @retval Others Errors occur.
> +
> +**/
> +EFI_STATUS
> +SetResourceConfigLangMemberInstance (
> + IN EFI_STRING *DestConfigLang,
> + IN UINTN MaxtLengthConfigLang,
> + IN REDFISH_FEATURE_ARRAY_TYPE_CONFIG_LANG *ConfigLangInstance
> + )
> +{
> + EFI_STRING ThisConfigLang;
> + EFI_STRING NewConfigLang;
> + CHAR16 InstanceStr [10];
> + INTN Index;
> + UINTN Length;
> + UINTN MaxStrLength;
> +
> + if (DestConfigLang == NULL || ConfigLangInstance == NULL) {
> + return EFI_INVALID_PARAMETER;
> + }
> + UnicodeSPrint ((CHAR16 *)&InstanceStr, 10, L"%d", ConfigLangInstance-
> >Index);
> +
> + ThisConfigLang = *DestConfigLang;
> + if (ThisConfigLang [0] == 0) {
> + //
> + // Return ConfigLangInstance->ConfigureLang
> + //
> + if (ConfigLangInstance->ConfigureLang == NULL) {
> + return EFI_INVALID_PARAMETER;
> + } else {
> + StrCatS(*DestConfigLang, MaxtLengthConfigLang, ConfigLangInstance-
> >ConfigureLang);
> + return EFI_SUCCESS;
> + }
> + }
> +
> + MaxStrLength = StrSize (ThisConfigLang) + StrSize
> ((EFI_STRING)&InstanceStr);
> + NewConfigLang = ThisConfigLang;
> + if (MaxtLengthConfigLang < MaxStrLength) {
> + NewConfigLang = (EFI_STRING)AllocateZeroPool(MaxStrLength);
> + if (NewConfigLang == NULL) {
> + DEBUG ((DEBUG_ERROR, "%a, Fail to allocate memory for
> NewConfigLang.\n", __FUNCTION__));
> + return EFI_OUT_OF_RESOURCES;
> + }
> + }
> + //
> + // Search the last "{"
> + //
> + Index = StrLen (ThisConfigLang) - 1;
> + while ((ThisConfigLang[Index] != '{') && (Index >= 0)) {
> + Index --;
> + };
> + if (Index == -1) {
> + if (NewConfigLang != ThisConfigLang) {
> + FreePool(NewConfigLang);
> + }
> + return EFI_NOT_FOUND;
> + }
> +
> + //
> + // Copy the string to a new string.
> + //
> + Length = 0;
> + while (Index >= 0) {
> + NewConfigLang [Index] = ThisConfigLang[Index];
> + Index --;
> + Length ++;
> + };
> + UnicodeSPrint ((CHAR16 *)(NewConfigLang + Length), MaxStrLength,
> L"%d", ConfigLangInstance->Index);
> + StrCatS (NewConfigLang, MaxStrLength, L"}");
> + if (NewConfigLang != ThisConfigLang) {
> + FreePool (ThisConfigLang);
> + }
> + *DestConfigLang = NewConfigLang;
> + 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) && Status == EFI_INVALID_PARAMETER) {
> + 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;
> +}
> +
> +/**
> +
> + Find "ETag" and "Location" from either HTTP header or Redfish response.
> +
> + @param[in] Response HTTP response
> + @param[out] Etag String buffer to return ETag
> + @param[out] Location String buffer to return Location
> +
> + @retval EFI_SUCCESS Data is found and returned.
> + @retval Others Errors occur.
> +
> +**/
> +EFI_STATUS
> +GetEtagAndLocation (
> + IN REDFISH_RESPONSE *Response,
> + OUT CHAR8 **Etag, OPTIONAL
> + OUT EFI_STRING *Location OPTIONAL
> + )
> +{
> + EDKII_JSON_VALUE JsonValue;
> + EDKII_JSON_VALUE OdataValue;
> + CHAR8 *OdataString;
> + CHAR8 *AsciiLocation;
> + EFI_HTTP_HEADER *Header;
> + EFI_STATUS Status;
> +
> + if (Response == NULL) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + if (Etag == NULL && Location == NULL) {
> + return EFI_SUCCESS;
> + }
> +
> + Status = EFI_SUCCESS;
> +
> + if (Etag != NULL) {
> + *Etag = NULL;
> +
> + if (*(Response->StatusCode) == HTTP_STATUS_200_OK) {
> + Header = HttpFindHeader (Response->HeaderCount, Response-
> >Headers, HTTP_HEADER_ETAG);
> + if (Header != NULL) {
> + *Etag = AllocateCopyPool (AsciiStrSize (Header->FieldValue), Header-
> >FieldValue);
> + ASSERT (*Etag != NULL);
> + }
> + }
> +
> + //
> + // No header is returned. Search payload for location.
> + //
> + if (*Etag == NULL && Response->Payload != NULL) {
> + JsonValue = RedfishJsonInPayload (Response->Payload);
> + if (JsonValue != NULL) {
> + OdataValue = JsonObjectGetValue (JsonValueGetObject (JsonValue),
> "@odata.etag");
> + if (OdataValue != NULL) {
> + OdataString = (CHAR8 *)JsonValueGetAsciiString (OdataValue);
> + if (OdataString != NULL) {
> + *Etag = AllocateCopyPool (AsciiStrSize (OdataString), OdataString);
> + ASSERT (*Etag != NULL);
> + }
> + }
> +
> + JsonValueFree (JsonValue);
> + }
> + }
> +
> + if (*Etag == NULL) {
> + Status = EFI_NOT_FOUND;
> + }
> + }
> +
> + if (Location != NULL) {
> + *Location = NULL;
> +
> + if (*(Response->StatusCode) == HTTP_STATUS_200_OK) {
> + Header = HttpFindHeader (Response->HeaderCount, Response-
> >Headers, HTTP_HEADER_LOCATION);
> + if (Header != NULL) {
> + AsciiLocation = AllocateCopyPool (AsciiStrSize (Header->FieldValue),
> Header->FieldValue);
> + ASSERT (AsciiLocation != NULL);
> + }
> + }
> +
> + //
> + // No header is returned. Search payload for location.
> + //
> + if (*Location == NULL && Response->Payload != NULL) {
> + JsonValue = RedfishJsonInPayload (Response->Payload);
> + if (JsonValue != NULL) {
> + OdataValue = JsonObjectGetValue (JsonValueGetObject (JsonValue),
> "@odata.id");
> + if (OdataValue != NULL) {
> + OdataString = (CHAR8 *)JsonValueGetAsciiString (OdataValue);
> + if (OdataString != NULL) {
> + AsciiLocation = AllocateCopyPool (AsciiStrSize (OdataString),
> OdataString);
> + ASSERT (AsciiLocation != NULL);
> + }
> + }
> +
> + JsonValueFree (JsonValue);
> + }
> + }
> +
> + if (AsciiLocation != NULL) {
> + *Location = StrAsciiToUnicode (AsciiLocation);
> + FreePool (AsciiLocation);
> + } else {
> + Status = EFI_NOT_FOUND;
> + }
> + }
> +
> + 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;
> +
> + 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;
> + }
> +
> + //
> + // Find ETag
> + //
> + Status = GetEtagAndLocation (&PostResponse, Etag, NULL);
> + if (EFI_ERROR (Status)) {
> + Status = EFI_DEVICE_ERROR;
> + }
> +
> + 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 EFI_STRING *Location,
> + OUT CHAR8 **Etag
> + )
> +{
> + REDFISH_PAYLOAD Payload;
> + EDKII_JSON_VALUE ResourceJsonValue;
> + REDFISH_RESPONSE PostResponse;
> + EFI_STATUS Status;
> +
> + 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.
> + //
> + Status = GetEtagAndLocation (&PostResponse, Etag, Location);
> + if (EFI_ERROR (Status)) {
> + Status = EFI_DEVICE_ERROR;
> + }
> +
> + RedfishFreeResponse (
> + PostResponse.StatusCode,
> + PostResponse.HeaderCount,
> + PostResponse.Headers,
> + PostResponse.Payload
> + );
> +
> + RedfishCleanupPayload (Payload);
> +
> +EXIT_FREE_JSON_VALUE:
> + JsonValueFree (ResourceJsonValue);
> +
> + return Status;
> +}
> +
> +/**
> +
> + Return redfish URI by given config language. It's call responsibility to
> release returned buffer.
> +
> + @param[in] ConfigLang ConfigLang to search.
> +
> + @retval NULL Can not find redfish uri.
> + @retval Other redfish uri is returned.
> +
> +**/
> +EFI_STRING
> +RedfishGetUri (
> + IN EFI_STRING ConfigLang
> + )
> +{
> + EFI_STATUS Status;
> + EFI_STRING Target;
> + EFI_STRING Found;
> + EFI_STRING TempStr;
> + EFI_STRING ResultStr;
> + EFI_STRING Head;
> + EFI_STRING CloseBracket;
> + UINTN TempStrSize;
> + UINTN RemainingLen;
> + UINTN ConfigLangLen;
> +
> + Status = RedfishLocateProtocol ((VOID **)&mConfigLangMapProtocol,
> &gEdkIIRedfishConfigLangMapProtocolGuid);
> + if (EFI_ERROR (Status)) {
> + DEBUG ((DEBUG_ERROR, "%a, fail to locate
> gEdkIIRedfishConfigLangMapProtocolGuid: %r\n", __FUNCTION__, Status));
> + return NULL;
> + }
> +
> + DEBUG ((REDFISH_DEBUG_TRACE, "%a, Get: %s\n", __FUNCTION__,
> ConfigLang));
> +
> + CloseBracket = StrStr (ConfigLang, L"{");
> + if (CloseBracket == NULL) {
> + return AllocateCopyPool (StrSize (ConfigLang), ConfigLang);
> + }
> +
> + //
> + // Remove leading "/v1" or "/redfish/v1" because we don't code
> + // configure language in this way.
> + //
> + Head = StrStr (ConfigLang, REDFISH_ROOT_PATH_UNICODE);
> + if (Head == NULL) {
> + Head = ConfigLang;
> + } else {
> + Head += 3;
> + }
> +
> + ResultStr = AllocateZeroPool (sizeof (CHAR16) * MAX_REDFISH_URL_LEN);
> + if (ResultStr == NULL) {
> + return NULL;
> + }
> +
> + //
> + // Go though ConfigLang and replace each {} with URL
> + //
> + do {
> + ConfigLangLen = StrLen (Head);
> + Target = CloseBracket;
> +
> + //
> + // Look for next ConfigLang
> + //
> + do {
> + Target += 1;
> + } while (*Target != '\0' && *Target != '}');
> +
> + //
> + // Invalid format. No '}' found
> + //
> + if (*Target == '\0') {
> + DEBUG ((DEBUG_ERROR, "%a, invalid format: %s\n", __FUNCTION__,
> ConfigLang));
> + return NULL;
> + }
> +
> + //
> + // Copy current ConfigLang to temporary string and do a query
> + //
> + Target += 1;
> + RemainingLen = StrLen (Target);
> + TempStrSize = (ConfigLangLen - RemainingLen + 1) * sizeof (CHAR16);
> + TempStr = AllocateCopyPool (TempStrSize, Head);
> + if (TempStr == NULL) {
> + return NULL;
> + }
> + TempStr[ConfigLangLen - RemainingLen] = '\0';
> +
> + Status = mConfigLangMapProtocol->Get (
> + mConfigLangMapProtocol,
> + RedfishGetTypeConfigLang,
> + TempStr,
> + &Found
> + );
> + if (EFI_ERROR (Status)) {
> + DEBUG ((DEBUG_ERROR, "%a, Can not find: %s\n", __FUNCTION__,
> TempStr));
> + return NULL;
> + }
> +
> + DEBUG ((REDFISH_DEBUG_TRACE, "%a, Found: %s\n", __FUNCTION__,
> Found));
> +
> + //
> + // Keep result in final string pool
> + //
> + StrCatS (ResultStr, MAX_REDFISH_URL_LEN, Found);
> + FreePool (TempStr);
> +
> + //
> + // Prepare for next ConfigLang
> + //
> + Head = Target;
> + CloseBracket = StrStr (Head, L"{");
> + } while (CloseBracket != NULL);
> +
> + //
> + // String which has no ConfigLang remaining
> + //
> + if (Head != '\0') {
> + StrCatS (ResultStr, MAX_REDFISH_URL_LEN, Head);
> + }
> +
> + DEBUG ((REDFISH_DEBUG_TRACE, "%a, return: %s\n", __FUNCTION__,
> ResultStr));
> +
> + return ResultStr;
> +}
> +
> +/**
> +
> + Return config language by given URI. It's call responsibility to release
> returned buffer.
> +
> + @param[in] Uri Uri to search.
> +
> + @retval NULL Can not find redfish uri.
> + @retval Other redfish uri is returned.
> +
> +**/
> +EFI_STRING
> +RedfishGetConfigLanguage (
> + IN EFI_STRING Uri
> + )
> +{
> + EFI_STATUS Status;
> + EFI_STRING ConfigLang;
> +
> + if (IS_EMPTY_STRING (Uri)) {
> + return NULL;
> + }
> +
> + DEBUG ((REDFISH_DEBUG_TRACE, "%a, search config lang for URI: %s\n",
> __FUNCTION__, Uri));
> +
> + Status = RedfishLocateProtocol ((VOID **)&mConfigLangMapProtocol,
> &gEdkIIRedfishConfigLangMapProtocolGuid);
> + if (EFI_ERROR (Status)) {
> + DEBUG ((DEBUG_ERROR, "%a, fail to locate
> gEdkIIRedfishConfigLangMapProtocolGuid: %r\n", __FUNCTION__, Status));
> + return NULL;
> + }
> +
> + ConfigLang = NULL;
> + Status = mConfigLangMapProtocol->Get (
> + mConfigLangMapProtocol,
> + RedfishGetTypeUri,
> + Uri,
> + &ConfigLang
> + );
> +
> +
> + return ConfigLang;
> +}
> +
> +/**
> +
> + Return config language from given URI and prperty name. It's call
> responsibility to release returned buffer.
> +
> + @param[in] Uri The URI to match
> + @param[in] PropertyName The property name of resource. This is
> optional.
> +
> + @retval NULL Can not find redfish uri.
> + @retval Other redfish uri is returned.
> +
> +**/
> +EFI_STRING
> +GetConfigureLang (
> + IN CHAR8 *Uri,
> + IN CHAR8 *PropertyName OPTIONAL
> + )
> +{
> + EFI_STRING ConfigLang;
> + UINTN StringSize;
> + EFI_STRING ResultStr;
> + EFI_STRING UnicodeUri;
> + EFI_STATUS Status;
> +
> + if (IS_EMPTY_STRING (Uri)) {
> + return NULL;
> + }
> +
> + StringSize = AsciiStrSize (Uri);
> + UnicodeUri = AllocatePool (StringSize * sizeof (CHAR16));
> + if (UnicodeUri == NULL) {
> + return NULL;
> + }
> +
> + Status = AsciiStrToUnicodeStrS (Uri, UnicodeUri, StringSize);
> + if (EFI_ERROR (Status)) {
> + return NULL;
> + }
> +
> + ConfigLang = RedfishGetConfigLanguage (UnicodeUri);
> + if (ConfigLang == NULL) {
> + return NULL;
> + }
> +
> + if (IS_EMPTY_STRING (PropertyName)) {
> + return ConfigLang;
> + }
> +
> + StringSize = StrSize (ConfigLang) + ((AsciiStrLen (PropertyName) + 1) *
> sizeof (CHAR16));
> + ResultStr = AllocatePool (StringSize);
> + if (ResultStr == NULL) {
> + return NULL;
> + }
> +
> + UnicodeSPrint (ResultStr, StringSize, L"%s/%a", ConfigLang,
> PropertyName);
> +
> + return ResultStr;
> +}
> +
> +/**
> +
> + Save Redfish URI in database for further use.
> +
> + @param[in] ConfigLang ConfigLang to save
> + @param[in] Uri Redfish Uri to save
> +
> + @retval EFI_INVALID_PARAMETR SystemId is NULL or EMPTY
> + @retval EFI_SUCCESS Redfish uri is saved
> +
> +**/
> +EFI_STATUS
> +RedfisSetRedfishUri (
> + IN EFI_STRING ConfigLang,
> + IN EFI_STRING Uri
> + )
> +{
> + EFI_STATUS Status;
> +
> + if (IS_EMPTY_STRING (ConfigLang) || IS_EMPTY_STRING (Uri)) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + Status = RedfishLocateProtocol ((VOID **)&mConfigLangMapProtocol,
> &gEdkIIRedfishConfigLangMapProtocolGuid);
> + if (EFI_ERROR (Status)) {
> + DEBUG ((DEBUG_ERROR, "%a, fail to locate
> gEdkIIRedfishConfigLangMapProtocolGuid: %r\n", __FUNCTION__, Status));
> + return Status;
> + }
> +
> + DEBUG ((REDFISH_DEBUG_TRACE, "%a, Saved: %s -> %s\n",
> __FUNCTION__, ConfigLang, Uri));
> +
> + return mConfigLangMapProtocol->Set (mConfigLangMapProtocol,
> ConfigLang, Uri);
> +}
> +
> +/**
> +
> + Get @odata.id from give HTTP payload. It's call responsibility to release
> returned buffer.
> +
> + @param[in] Payload HTTP payload
> +
> + @retval NULL Can not find @odata.id from given payload.
> + @retval Others odata.id string is returned.
> +
> +**/
> +EFI_STRING
> +GetOdataId (
> + IN REDFISH_PAYLOAD *Payload
> + )
> +{
> + EDKII_JSON_VALUE *JsonValue;
> + EDKII_JSON_VALUE *OdataId;
> + EFI_STRING OdataIdString;
> +
> + if (Payload == NULL) {
> + return NULL;
> + }
> +
> + JsonValue = RedfishJsonInPayload (Payload);
> + if (!JsonValueIsObject (JsonValue)) {
> + return NULL;
> + }
> +
> + OdataId = JsonObjectGetValue (JsonValueGetObject (JsonValue),
> "@odata.id");
> + if (!JsonValueIsString (OdataId)) {
> + return NULL;
> + }
> +
> + OdataIdString = JsonValueGetUnicodeString (OdataId);
> + if (OdataIdString == NULL) {
> + return NULL;
> + }
> +
> + return AllocateCopyPool (StrSize (OdataIdString), OdataIdString);
> +}
> +
> +
> +/**
> +
> + Get the property name by given Configure Langauge.
> +
> + @param[in] ResourceUri URI of root of resource.
> + @param[in] ConfigureLang Configure Language string.
> +
> + @retval EFI_STRING Pointer to property name.
> + @retval NULL There is error.
> +
> +**/
> +EFI_STRING
> +GetPropertyFromConfigureLang (
> + IN EFI_STRING ResourceUri,
> + IN EFI_STRING ConfigureLang
> + )
> +{
> + EFI_STATUS Status;
> + EFI_STRING TempString;
> +
> + if (ConfigureLang == NULL || ResourceUri == NULL) {
> + return NULL;
> + }
> +
> + Status = IsRedpathArray (ConfigureLang, NULL, &TempString);
> + if (!EFI_ERROR(Status)) {
> + TempString += 2; // Advance two characters for '}' and '/'
> + return TempString;
> + }
> + if (Status != EFI_NOT_FOUND) {
> + return NULL;
> + }
> + //
> + // The ConigLang has no '{}'
> + //
> + if (GetNumberOfRedpathNodes (ConfigureLang) == 1) {
> + return NULL;
> + }
> +
> + if (GetRedpathNodeByIndex (ConfigureLang, 0, &TempString) == NULL) {
> + return NULL;
> + }
> + //
> + // Advance two characters to the starting
> + // pointer of next node.
> + //
> + return TempString + 2;
> +}
> +
> +/**
> +
> + 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;
> +}
> +
> +/**
> +
> + Return the last string of configure language. Any modification to returned
> + string will change ConfigureLanguage.
> +
> + @param[in] ConfigureLanguage Configure language string
> +
> + @retval EFI_STRING Attribute name is returned
> + @retval NULL Error occurs
> +
> +**/
> +EFI_STRING
> +GetAttributeNameFromConfigLanguage (
> + IN EFI_STRING ConfigureLanguage
> + )
> +{
> + UINTN StringLen;
> + UINTN Index;
> +
> + if (IS_EMPTY_STRING (ConfigureLanguage)) {
> + return NULL;
> + }
> +
> + StringLen = StrLen (ConfigureLanguage);
> + for (Index = StringLen - 1; Index >= 0; Index--) {
> + if (ConfigureLanguage[Index] == '/') {
> + return &ConfigureLanguage[Index + 1];
> + }
> + }
> +
> + return NULL;
> +}
> +
> +/**
> +
> + Get the property string value in array 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.
> + @param[out] ArraySize The size of returned array.
> +
> + @retval CHAR8 ** Returned string array. NULL while error happens.
> +
> +**/
> +CHAR8 **
> +GetPropertyStringArrayValue (
> + IN CHAR8 *Schema,
> + IN CHAR8 *Version,
> + IN EFI_STRING PropertyName,
> + IN EFI_STRING ConfigureLang,
> + OUT UINTN *ArraySize
> + )
> +{
> + EFI_STATUS Status;
> + EDKII_REDFISH_VALUE RedfishValue;
> + EFI_STRING ConfigureLangBuffer;
> + UINTN BufferSize;
> + CHAR8 **StringArray;
> + UINTN Index;
> +
> + if (IS_EMPTY_STRING (Schema) || IS_EMPTY_STRING (Version) ||
> IS_EMPTY_STRING (ConfigureLang) || IS_EMPTY_STRING (PropertyName)
> || ArraySize == NULL) {
> + return NULL;
> + }
> +
> + *ArraySize = 0;
> +
> + //
> + // Configure Language buffer.
> + //
> + BufferSize = sizeof (CHAR16) * MAX_CONF_LANG_LEN;
> + ConfigureLangBuffer = AllocatePool (BufferSize);
> + if (ConfigureLangBuffer == NULL) {
> + DEBUG ((DEBUG_ERROR, "%a, out of resource\n", __FUNCTION__));
> + 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_ARRAY) {
> + DEBUG ((DEBUG_ERROR, "%a, %a.%a %s value is not string array type\n",
> __FUNCTION__, Schema, Version, ConfigureLang));
> + return NULL;
> + }
> +
> + StringArray = AllocatePool (sizeof (CHAR8 *) * RedfishValue.ArrayCount);
> + if (StringArray == NULL) {
> + DEBUG ((DEBUG_ERROR, "%a, out of resource\n", __FUNCTION__));
> + return NULL;
> + }
> +
> + *ArraySize = RedfishValue.ArrayCount;
> + for (Index = 0; Index < RedfishValue.ArrayCount; Index++) {
> + StringArray[Index] = RedfishValue.Value.StringArray[Index];
> + }
> +
> + return StringArray;
> +}
> +
> +/**
> +
> + Get the property numeric value in array 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.
> + @param[out] ArraySize The size of returned array.
> +
> + @retval INT64 * Returned integer array. NULL while error happens.
> +
> +**/
> +INT64 *
> +GetPropertyNumericArrayValue (
> + IN CHAR8 *Schema,
> + IN CHAR8 *Version,
> + IN EFI_STRING PropertyName,
> + IN EFI_STRING ConfigureLang,
> + OUT UINTN *ArraySize
> + )
> +{
> + EFI_STATUS Status;
> + EDKII_REDFISH_VALUE RedfishValue;
> + EFI_STRING ConfigureLangBuffer;
> + UINTN BufferSize;
> + INT64 *IntegerArray;
> + UINTN Index;
> +
> + if (IS_EMPTY_STRING (Schema) || IS_EMPTY_STRING (Version) ||
> IS_EMPTY_STRING (ConfigureLang) || IS_EMPTY_STRING (PropertyName)
> || ArraySize == NULL) {
> + return NULL;
> + }
> +
> + *ArraySize = 0;
> +
> + //
> + // Configure Language buffer.
> + //
> + BufferSize = sizeof (CHAR16) * MAX_CONF_LANG_LEN;
> + ConfigureLangBuffer = AllocatePool (BufferSize);
> + if (ConfigureLangBuffer == NULL) {
> + DEBUG ((DEBUG_ERROR, "%a, out of resource\n", __FUNCTION__));
> + 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_ARRAY) {
> + DEBUG ((DEBUG_ERROR, "%a, %a.%a %s value is not string array type\n",
> __FUNCTION__, Schema, Version, ConfigureLang));
> + return NULL;
> + }
> +
> + IntegerArray = AllocatePool (sizeof (INT64) * RedfishValue.ArrayCount);
> + if (IntegerArray == NULL) {
> + DEBUG ((DEBUG_ERROR, "%a, out of resource\n", __FUNCTION__));
> + return NULL;
> + }
> +
> + *ArraySize = RedfishValue.ArrayCount;
> + for (Index = 0; Index < RedfishValue.ArrayCount; Index++) {
> + IntegerArray[Index] = RedfishValue.Value.IntegerArray[Index];
> + }
> +
> + return IntegerArray;
> +}
> +
> +/**
> +
> + Get the property boolean value in array 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.
> + @param[out] ArraySize The size of returned array.
> +
> + @retval BOOLEAN * Returned boolean array. NULL while error
> happens.
> +
> +**/
> +BOOLEAN *
> +GetPropertyBooleanArrayValue (
> + IN CHAR8 *Schema,
> + IN CHAR8 *Version,
> + IN EFI_STRING PropertyName,
> + IN EFI_STRING ConfigureLang,
> + OUT UINTN *ArraySize
> + )
> +{
> + EFI_STATUS Status;
> + EDKII_REDFISH_VALUE RedfishValue;
> + EFI_STRING ConfigureLangBuffer;
> + UINTN BufferSize;
> + BOOLEAN *BooleanArray;
> + UINTN Index;
> +
> + if (IS_EMPTY_STRING (Schema) || IS_EMPTY_STRING (Version) ||
> IS_EMPTY_STRING (ConfigureLang) || IS_EMPTY_STRING (PropertyName)
> || ArraySize == NULL) {
> + return NULL;
> + }
> +
> + *ArraySize = 0;
> +
> + //
> + // Configure Language buffer.
> + //
> + BufferSize = sizeof (CHAR16) * MAX_CONF_LANG_LEN;
> + ConfigureLangBuffer = AllocatePool (BufferSize);
> + if (ConfigureLangBuffer == NULL) {
> + DEBUG ((DEBUG_ERROR, "%a, out of resource\n", __FUNCTION__));
> + 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_ARRAY) {
> + DEBUG ((DEBUG_ERROR, "%a, %a.%a %s value is not string array type\n",
> __FUNCTION__, Schema, Version, ConfigureLang));
> + return NULL;
> + }
> +
> + BooleanArray = AllocatePool (sizeof (INT64) * RedfishValue.ArrayCount);
> + if (BooleanArray == NULL) {
> + DEBUG ((DEBUG_ERROR, "%a, out of resource\n", __FUNCTION__));
> + return NULL;
> + }
> +
> + *ArraySize = RedfishValue.ArrayCount;
> + for (Index = 0; Index < RedfishValue.ArrayCount; Index++) {
> + BooleanArray[Index] = RedfishValue.Value.BooleanArray[Index];
> + }
> +
> + return BooleanArray;
> +}
> +
> +/**
> +
> + Free the list of empty property key values.
> +
> + @param[in] EmptyPropKeyValueListHead The head of
> RedfishCS_EmptyProp_KeyValue
> +
> +**/
> +VOID
> +FreeEmptyPropKeyValueList (
> + RedfishCS_EmptyProp_KeyValue *EmptyPropKeyValueListHead
> + )
> +{
> + RedfishCS_EmptyProp_KeyValue *NextEmptyPropKeyValueList;
>
> - if (StrCmp (UnifiedConfigureLangPool[Index2].ConfigureLang,
> UnifiedConfigureLang) == 0) {
> - Duplicated = TRUE;
> - break;
> - }
> + while (EmptyPropKeyValueListHead != NULL) {
> + NextEmptyPropKeyValueList = EmptyPropKeyValueListHead-
> >NextKeyValuePtr;
> + if (EmptyPropKeyValueListHead->Value->DataValue.CharPtr != NULL) {
> + FreePool(EmptyPropKeyValueListHead->Value->DataValue.CharPtr);
> }
> -
> - if (Duplicated) {
> - FreePool (UnifiedConfigureLang);
> - continue;
> + if (EmptyPropKeyValueListHead->Value != NULL) {
> + FreePool(EmptyPropKeyValueListHead->Value);
> }
> -
> - if (UnifiedConfigureLangList->Count >=
> BIOS_CONFIG_TO_REDFISH_REDPATH_POOL_SIZE) {
> - FreePool (UnifiedConfigureLang);
> - Status = EFI_BUFFER_TOO_SMALL;
> - break;
> + if (EmptyPropKeyValueListHead->KeyNamePtr != NULL) {
> + FreePool(EmptyPropKeyValueListHead->KeyNamePtr);
> }
> + FreePool (EmptyPropKeyValueListHead);
> + EmptyPropKeyValueListHead = NextEmptyPropKeyValueList;
> + };
> +}
>
> - //
> - // New configure language. Keep it in Pool
> - //
> +/**
>
> - UnifiedConfigureLangPool[UnifiedConfigureLangList-
> >Count].ConfigureLang = UnifiedConfigureLang;
> - UnifiedConfigureLangPool[UnifiedConfigureLangList->Count].Index =
> ArrayIndex;
> - ++UnifiedConfigureLangList->Count;
> - }
> + Create a new entry of RedfishCS_EmptyProp_KeyValue
>
> - FreePool (ConfigureLangList);
> + @param[in] KeyName The key name.
> + @param[in] RedfishValue Redfish vale of this key.
>
> - //
> - // Prepare the result to caller.
> - //
> - UnifiedConfigureLangList->List = AllocateCopyPool (sizeof
> (REDFISH_FEATURE_ARRAY_TYPE_CONFIG_LANG) *
> UnifiedConfigureLangList->Count, UnifiedConfigureLangPool);
> +* @retval RedfishCS_EmptyProp_KeyValue Return the new
> RedfishCS_EmptyProp_KeyValue.
> +* NULL means no new entry is created.
>
> - return Status;
> +**/
> +RedfishCS_EmptyProp_KeyValue *
> +NewEmptyPropKeyValueFromRedfishValue (
> + IN EFI_STRING KeyName,
> + IN EDKII_REDFISH_VALUE *RedfishValue
> + )
> +{
> + RedfishCS_EmptyProp_KeyValue *EmptyPropKeyValue;
> + RedfishCS_Vague *VagueValue;
> + RedfishCS_char *KeyNameChar;
> + VOID *Data;
> + UINTN DataSize;
> + INT32 Bool32;
> +
> + KeyNameChar = StrUnicodeToAscii(KeyName);
> + if (KeyNameChar == NULL) {
> + DEBUG ((DEBUG_ERROR, "%a, Failed to convert unicode to ASCII.\n",
> __FUNCTION__));
> + return NULL;
> + }
> + EmptyPropKeyValue = (RedfishCS_EmptyProp_KeyValue
> *)AllocateZeroPool (sizeof (RedfishCS_EmptyProp_KeyValue));
> + if (EmptyPropKeyValue == NULL) {
> + DEBUG ((DEBUG_ERROR, "%a, Failed to allocate memory for
> EmptyPropKeyValue\n", __FUNCTION__));
> + return NULL;
> + }
> + VagueValue = (RedfishCS_Vague *)AllocateZeroPool (sizeof
> (RedfishCS_Vague));
> + if (VagueValue == NULL) {
> + DEBUG ((DEBUG_ERROR, "%a, Failed to allocate memory for
> VagueValue\n", __FUNCTION__));
> + FreePool (EmptyPropKeyValue);
> + return NULL;
> + }
> +
> + if (RedfishValue->Type == REDFISH_VALUE_TYPE_BOOLEAN) {
> + VagueValue->DataType = RedfishCS_Vague_DataType_Bool;
> + DataSize = sizeof (BOOLEAN);
> + //
> + // Redfish JSON to C strcuture converter uses
> + // "int" for the BOOLEAN.
> + //
> + Bool32 = (INT32)RedfishValue->Value.Boolean;
> + Data = (VOID *)&Bool32;
> + } else if (RedfishValue->Type == REDFISH_VALUE_TYPE_INTEGER) {
> + VagueValue->DataType = RedfishCS_Vague_DataType_Int64;
> + DataSize = sizeof (INT64);
> + Data = (VOID *)&RedfishValue->Value.Integer;
> + } else if (RedfishValue->Type == REDFISH_VALUE_TYPE_STRING) {
> + VagueValue->DataType = RedfishCS_Vague_DataType_String;
> + DataSize = AsciiStrSize(RedfishValue->Value.Buffer);
> + Data = (VOID *)RedfishValue->Value.Buffer;
> + } else {
> + DEBUG ((DEBUG_ERROR, "%a, wrong type of RedfishValue: %x\n",
> __FUNCTION__, RedfishValue->Type));
> + FreePool (VagueValue);
> + FreePool (EmptyPropKeyValue);
> + return NULL;
> + }
> + VagueValue->DataValue.CharPtr = (RedfishCS_char
> *)AllocateCopyPool(DataSize, Data);
> + EmptyPropKeyValue->Value = VagueValue;
> + EmptyPropKeyValue->KeyNamePtr = KeyNameChar;
> + return EmptyPropKeyValue;
> }
>
> /**
>
> - Create HTTP payload and send them to redfish service with PATCH method.
> + Get the property value in the vague type.
>
> - @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.
> + @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.
> + @param[out] NumberOfValues Return the number of vague type of
> values
>
> - @retval EFI_SUCCESS Data is sent to redfish service successfully.
> - @retval Others Errors occur.
> + @retval RedfishCS_EmptyProp_KeyValue The pointer to the structure
> + of vague type of values.
>
> **/
> -EFI_STATUS
> -CreatePayloadToPatchResource (
> - IN REDFISH_SERVICE *Service,
> - IN REDFISH_PAYLOAD *TargetPayload,
> - IN CHAR8 *Json,
> - OUT CHAR8 **Etag
> +RedfishCS_EmptyProp_KeyValue *
> +GetPropertyVagueValue (
> + IN CHAR8 *Schema,
> + IN CHAR8 *Version,
> + IN EFI_STRING PropertyName,
> + IN EFI_STRING ConfigureLang,
> + OUT UINT32 *NumberOfValues
> )
> {
> - 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;
> + EFI_STATUS Status;
> + RedfishCS_EmptyProp_KeyValue *EmptyPropKeyValueList;
> + RedfishCS_EmptyProp_KeyValue *PreEmptyPropKeyValueList;
> + RedfishCS_EmptyProp_KeyValue *FirstEmptyPropKeyValueList;
> + EDKII_REDFISH_VALUE RedfishValue;
> + EFI_STRING ConfigureLangBuffer;
> + EFI_STRING KeyName;
> + EFI_STRING *ConfigureLangList;
> + EFI_STRING SearchPattern;
> + UINTN BufferSize;
> + UINTN ConfigListCount;
> + UINTN ConfigListCountIndex;
>
> - if (Service == NULL || TargetPayload == NULL || IS_EMPTY_STRING (Json)
> || Etag == NULL) {
> - return EFI_INVALID_PARAMETER;
> + if (IS_EMPTY_STRING (Schema) || IS_EMPTY_STRING (Version) ||
> IS_EMPTY_STRING (ConfigureLang) || IS_EMPTY_STRING (PropertyName)) {
> + return NULL;
> }
>
> - 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;
> + //
> + // Configure Language buffer.
> + //
> + BufferSize = sizeof (CHAR16) * MAX_CONF_LANG_LEN;
> + ConfigureLangBuffer = AllocatePool (BufferSize);
> + if (ConfigureLangBuffer == NULL) {
> + DEBUG ((DEBUG_ERROR, "%a, Failed to allocate memory for
> ConfigureLangBuffer\n", __FUNCTION__));
> + return NULL;
> }
> + UnicodeSPrint (ConfigureLangBuffer, BufferSize, L"%s/%s", ConfigureLang,
> PropertyName);
>
> - ZeroMem (&PostResponse, sizeof (REDFISH_RESPONSE));
> - Status = RedfishPatchToPayload (TargetPayload, Payload, &PostResponse);
> + //
> + // Initial search pattern
> + //
> + BufferSize = (StrLen (ConfigureLangBuffer) + StrLen (L"/.*") + 1) * sizeof
> (CHAR16); // Increase one for the NULL terminator.
> + SearchPattern = AllocatePool (BufferSize);
> + if (SearchPattern == NULL) {
> + DEBUG ((DEBUG_ERROR, "%a, Failed to allocate memory for
> SearchPattern\n", __FUNCTION__));
> + FreePool (ConfigureLangBuffer);
> + return NULL;
> + }
> + BufferSize = BufferSize / sizeof (CHAR16);
> + StrCpyS (SearchPattern, BufferSize, ConfigureLangBuffer);
> + StrCatS (SearchPattern, BufferSize, L"/.*");
> + Status = RedfishPlatformConfigGetConfigureLang (Schema, Version,
> SearchPattern, &ConfigureLangList, &ConfigListCount);
> if (EFI_ERROR (Status)) {
> - DEBUG ((DEBUG_ERROR, "%a:%d Failed to PATCH payload to Redfish
> service.\n",__FUNCTION__, __LINE__));
> - goto EXIT_FREE_JSON_VALUE;
> + DEBUG ((DEBUG_ERROR, "%a, %a.%a Get configure language of vague
> type values of %s failed: %r\n", __FUNCTION__, Schema, Version,
> ConfigureLangBuffer, Status));
> + goto ErrorLeave;
> }
>
> -
> //
> - // Keep etag.
> + // Build up the list of RedfishCS_EmptyProp_KeyValue.
> //
> - *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);
> - }
> - }
> - }
> + ConfigListCountIndex = 0;
> + PreEmptyPropKeyValueList = NULL;
> + FirstEmptyPropKeyValueList = NULL;
> + while (ConfigListCountIndex < ConfigListCount) {
> + Status = RedfishPlatformConfigGetValue(Schema, Version,
> ConfigureLangList [ConfigListCountIndex], &RedfishValue);
> + if (EFI_ERROR (Status)) {
> + DEBUG ((DEBUG_ERROR, "%a, %a.%a query current setting for %s failed:
> %r\n", __FUNCTION__, Schema, Version, ConfigureLangList
> [ConfigListCountIndex], Status));
> + goto ErrorLeave;
> }
> - }
> -
> - RedfishFreeResponse (
> - PostResponse.StatusCode,
> - PostResponse.HeaderCount,
> - PostResponse.Headers,
> - PostResponse.Payload
> - );
> + //
> + // Get the key name.
> + //
> + KeyName = GetAttributeNameFromConfigLanguage (ConfigureLangList
> [ConfigListCountIndex]);
> + //
> + // Create an entry of RedfishCS_EmptyProp_KeyValue.
> + //
> + EmptyPropKeyValueList = NewEmptyPropKeyValueFromRedfishValue
> (KeyName, &RedfishValue);
> + if (EmptyPropKeyValueList == NULL) {
> + DEBUG ((DEBUG_ERROR, "%a, Failed to create an entry of
> EmptyPropKeyValueList\n", __FUNCTION__));
> + ConfigListCountIndex ++;
> + continue;
> + }
> + //
> + // Link the RedfishCS_EmptyProp_KeyValue list.
> + //
> + if (PreEmptyPropKeyValueList != NULL) {
> + PreEmptyPropKeyValueList->NextKeyValuePtr =
> EmptyPropKeyValueList;
> + } else {
> + FirstEmptyPropKeyValueList = EmptyPropKeyValueList;
> + }
> + PreEmptyPropKeyValueList = EmptyPropKeyValueList;
> + ConfigListCountIndex ++;
> + };
> + goto LeaveFunction;
>
> -EXIT_FREE_JSON_VALUE:
> - if (Payload != NULL) {
> - RedfishCleanupPayload (Payload);
> +ErrorLeave:;
> + if (FirstEmptyPropKeyValueList != NULL) {
> + FreeEmptyPropKeyValueList (FirstEmptyPropKeyValueList);
> }
> + FirstEmptyPropKeyValueList = NULL;
>
> - JsonValueFree (ResourceJsonValue);
> +LeaveFunction:
> + if (SearchPattern != NULL) {
> + FreePool (SearchPattern);
> + }
> + if (ConfigureLangBuffer != NULL) {
> + FreePool (ConfigureLangBuffer);
> + }
> + FreePool (ConfigureLangList);
>
> - return Status;
> + *NumberOfValues = (UINT32)ConfigListCount;
> + return FirstEmptyPropKeyValueList;
> }
>
> /**
>
> - Create HTTP payload and send them to redfish service with POST method.
> + Check and see if we need to do provisioning for this property.
>
> - @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.
> + @param[in] PropertyBuffer Pointer to property instance.
> + @param[in] ProvisionMode TRUE if we are in provision mode. FALSE
> otherwise.
>
> - @retval EFI_SUCCESS Data is sent to redfish service successfully.
> - @retval Others Errors occur.
> + @retval TRUE Provision is required.
> + @retval FALSE Provision is not required.
>
> **/
> -EFI_STATUS
> -CreatePayloadToPostResource (
> - IN REDFISH_SERVICE *Service,
> - IN REDFISH_PAYLOAD *TargetPayload,
> - IN CHAR8 *Json,
> - OUT CHAR8 **Location,
> - OUT CHAR8 **Etag
> +BOOLEAN
> +PropertyChecker (
> + IN VOID *PropertyBuffer,
> + IN BOOLEAN ProvisionMode
> )
> {
> - 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 (ProvisionMode) {
> + return TRUE;
> + }
>
> - if (Service == NULL || TargetPayload == NULL || IS_EMPTY_STRING (Json)
> || Location == NULL || Etag == NULL) {
> - return EFI_INVALID_PARAMETER;
> + if (!ProvisionMode && PropertyBuffer != NULL) {
> + return TRUE;
> }
>
> - 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;
> + return FALSE;
> +}
> +
> +/**
> +
> + Check and see if ETAG is identical to what we keep in system.
> +
> + @param[in] Uri URI requested
> + @param[in] EtagInHeader ETAG string returned from HTTP request.
> + @param[in] EtagInJson ETAG string in JSON body.
> +
> + @retval TRUE ETAG is identical.
> + @retval FALSE ETAG is changed.
> +
> +**/
> +BOOLEAN
> +CheckEtag (
> + IN EFI_STRING Uri,
> + IN CHAR8 *EtagInHeader,
> + IN CHAR8 *EtagInJson
> + )
> +{
> + CHAR8 *EtagInDb;
> +
> + if (IS_EMPTY_STRING (Uri)) {
> + return FALSE;
> }
>
> - 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;
> + if (IS_EMPTY_STRING (EtagInHeader) && IS_EMPTY_STRING (EtagInJson))
> {
> + return FALSE;
> }
>
> //
> - // per Redfish spec. the URL of new eresource will be returned in
> "Location" header.
> + // Check ETAG to see if we need to consume it
> //
> - *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);
> - }
> - }
> + EtagInDb = NULL;
> + EtagInDb = GetEtagWithUri (Uri);
> + if (EtagInDb == NULL) {
> + DEBUG ((REDFISH_DEBUG_TRACE, "%a, no ETAG record cound be found
> for: %s\n", __FUNCTION__, Uri));
> + return FALSE;
> + }
>
> - OdataIdValue = JsonObjectGetValue (JsonValueGetObject (JsonValue),
> "@odata.etag");
> - if (OdataIdValue != NULL) {
> - OdataIdString = (CHAR8 *)JsonValueGetAsciiString (OdataIdValue);
> - if (OdataIdString != NULL) {
> - *Etag = AllocateCopyPool (AsciiStrSize (OdataIdString), OdataIdString);
> - }
> - }
> - }
> + if (EtagInHeader != NULL) {
> + if (AsciiStrCmp (EtagInDb, EtagInHeader) == 0) {
> + FreePool (EtagInDb);
> + return TRUE;
> }
> }
>
> - //
> - // This is not expected as service does not follow spec.
> - //
> - if (*Location == NULL) {
> - Status = EFI_DEVICE_ERROR;
> + if (EtagInJson != NULL) {
> + if (AsciiStrCmp (EtagInDb, EtagInJson) == 0) {
> + FreePool (EtagInDb);
> + return TRUE;
> + }
> }
>
> - RedfishFreeResponse (
> - PostResponse.StatusCode,
> - PostResponse.HeaderCount,
> - PostResponse.Headers,
> - PostResponse.Payload
> - );
> -
> - RedfishCleanupPayload (Payload);
> -
> -EXIT_FREE_JSON_VALUE:
> - JsonValueFree (JsonValue);
> - JsonValueFree (ResourceJsonValue);
> + FreePool (EtagInDb);
>
> - return Status;
> + return FALSE;
> }
>
> /**
> + Check and see if given ObjectName can be found in JsonObj or not
>
> - Find Redfish Resource Config Protocol that supports given schema and
> version.
> + @param[in] JsonObj JSON object to search
> + @param[in] ObjectName Object name
>
> - @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.
> + @retval EDKII_JSON_VALUE * Pointer to Json object is found. NULL
> otherwise.
>
> **/
> -EDKII_REDFISH_RESOURCE_CONFIG_PROTOCOL *
> -GetRedfishResourceConfigProtocol (
> - IN CHAR8 *Schema,
> - IN CHAR8 *Major,
> - IN CHAR8 *Minor,
> - IN CHAR8 *Errata
> +EDKII_JSON_VALUE *
> +MatchJsonObject (
> + IN EDKII_JSON_VALUE *JsonObj,
> + IN CHAR8 *ObjectName
> )
> {
> - EFI_STATUS Status;
> - EFI_HANDLE *HandleBuffer;
> - UINTN NumberOfHandles;
> - UINTN Index;
> - EDKII_REDFISH_RESOURCE_CONFIG_PROTOCOL *Protocol;
> - REDFISH_SCHEMA_INFO SchemaInfo;
> - BOOLEAN Found;
> + EDKII_JSON_VALUE N;
> + CHAR8 *Key;
> + EDKII_JSON_VALUE Value;
>
> - if (IS_EMPTY_STRING (Schema) || IS_EMPTY_STRING (Major) ||
> IS_EMPTY_STRING (Minor) || IS_EMPTY_STRING (Errata)) {
> + if (JsonObj == NULL || IS_EMPTY_STRING (ObjectName)) {
> return NULL;
> }
>
> - Status = gBS->LocateHandleBuffer (
> - ByProtocol,
> - &gEdkIIRedfishResourceConfigProtocolGuid,
> - NULL,
> - &NumberOfHandles,
> - &HandleBuffer
> - );
> - if (EFI_ERROR (Status)) {
> + if (!JsonValueIsObject (JsonObj)) {
> 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;
> + EDKII_JSON_OBJECT_FOREACH_SAFE (JsonObj, N, Key, Value) {
> + if (AsciiStrCmp (Key, ObjectName) == 0) {
> + return Value;
> }
> -
> - 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);
> + return NULL;
> }
>
> /**
>
> - Get supported schema list by given specify schema name.
> + Check and see if given property is in JSON context or not
>
> - @param[in] Schema Schema type name.
> - @param[out] SchemaInfo Returned schema information.
> + @param[in] Property Property name string
> + @param[in] Json The JSON context to search.
>
> - @retval EFI_SUCCESS Schema information is returned successfully.
> - @retval Others Errors occur.
> + @retval TRUE Property is found in JSON context
> + @retval FALSE Property is not in JSON context
>
> **/
> -EFI_STATUS
> -GetSupportedSchemaVersion (
> - IN CHAR8 *Schema,
> - OUT REDFISH_SCHEMA_INFO *SchemaInfo
> +BOOLEAN
> +MatchPropertyWithJsonContext (
> + IN EFI_STRING Property,
> + IN CHAR8 *Json
> )
> {
> - EFI_STATUS Status;
> - CHAR8 *SupportSchema;
> - CHAR8 *SchemaName;
> - UINTN Index;
> - UINTN Index2;
> - BOOLEAN Found;
> + CHAR8 *AsciiProperty;
> + CHAR8 *PropertyNode;
> + UINTN Index;
> + EDKII_JSON_VALUE *JsonObj;
> + EDKII_JSON_VALUE *MatchObj;
> + EDKII_JSON_TYPE JsonType;
>
> - if (IS_EMPTY_STRING (Schema) || SchemaInfo == NULL) {
> - return EFI_INVALID_PARAMETER;
> + if (IS_EMPTY_STRING (Property) || IS_EMPTY_STRING (Json)) {
> + return FALSE;
> }
>
> - Status = RedfishPlatformConfigGetSupportedSchema (NULL,
> &SupportSchema);
> - if (EFI_ERROR (Status)) {
> - return Status;
> + JsonObj = JsonLoadString (Json, 0, NULL);
> + if (JsonObj == NULL || !JsonValueIsObject (JsonObj)) {
> + return FALSE;
> }
>
> - 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;
> + AsciiProperty = StrUnicodeToAscii (Property);
> + if (AsciiProperty == NULL) {
> + return FALSE;
> }
>
> - 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');
> + Index = 0;
> + PropertyNode = AsciiProperty;
> + MatchObj = JsonObj;
>
> - //
> - // Skip '.' and 'v'
> - //
> - Index += 2;
> + //
> + // Walk through property and find corresponding object in JSON input
> + //
> + while (AsciiProperty[Index] != '\0') {
>
> - //
> - // forward to '_'
> - //
> - Index2 = Index;
> - while (SchemaName[Index2] != '\0' && SchemaName[Index2] != '_') {
> - ++Index2;
> + if (AsciiProperty[Index] == '/') {
> + AsciiProperty[Index] = '\0';
> + MatchObj = MatchJsonObject (MatchObj, PropertyNode);
> + if (MatchObj == NULL) {
> + PropertyNode = NULL;
> + break;
> + }
> +
> + PropertyNode = &AsciiProperty[Index + 1];
> }
> - ASSERT (SchemaName[Index2] != '\0');
>
> - AsciiStrnCpyS (SchemaInfo->Major, REDFISH_SCHEMA_VERSION_SIZE,
> &SchemaName[Index], (Index2 - Index));
> - Index = Index2;
> + Index++;
> + }
>
> - //
> - // Skip '_'
> - //
> - ++Index;
> + if (PropertyNode != NULL) {
> + MatchObj = MatchJsonObject (MatchObj, PropertyNode);
> + }
>
> + //
> + // Value check
> + //
> + if (MatchObj != NULL) {
> //
> - // forward to '_'
> + // If object has empty value, treat it as not matching
> //
> - Index2 = Index;
> - while (SchemaName[Index2] != '\0' && SchemaName[Index2] != '_') {
> - ++Index2;
> + JsonType = JsonGetType (MatchObj);
> + switch (JsonType) {
> + case EdkiiJsonTypeObject:
> + if (JsonValueIsNull (MatchObj)) {
> + MatchObj = NULL;
> + }
> + break;
> + case EdkiiJsonTypeArray:
> + if (JsonArrayCount (MatchObj) == 0) {
> + MatchObj = NULL;
> + }
> + break;
> + case EdkiiJsonTypeString:
> + if (IS_EMPTY_STRING (JsonValueGetString (MatchObj))) {
> + MatchObj = NULL;
> + }
> + break;
> + case EdkiiJsonTypeNull:
> + MatchObj = NULL;
> + break;
> + default:
> + break;
> }
> - 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.
> + FreePool (AsciiProperty);
>
> - @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);
> + return (MatchObj == NULL ? FALSE : TRUE);
> }
>
> /**
>
> - Get schema information by given protocol and service instance.
> + Create string array and append to arry node in Redfish JSON convert
> format.
>
> - @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.
> + @param[in,out] Head The head of string array.
> + @param[in] StringArray Input string array.
> + @param[in] ArraySize The size of StringArray.
>
> - @retval EFI_SUCCESS Schema information is returned successfully.
> - @retval Others Errors occur.
> + @retval EFI_SUCCESS String array is created successfully.
> + @retval Others Error happens
>
> **/
> EFI_STATUS
> -GetRedfishSchemaInfo (
> - IN REDFISH_SERVICE *RedfishService,
> - IN EFI_REST_JSON_STRUCTURE_PROTOCOL *JsonStructProtocol,
> - IN CHAR8 *Uri,
> - OUT REDFISH_SCHEMA_INFO *SchemaInfo
> +AddRedfishCharArray (
> + IN OUT RedfishCS_char_Array **Head,
> + IN CHAR8 **StringArray,
> + IN UINTN ArraySize
> )
> {
> - EFI_STATUS Status;
> - REDFISH_RESPONSE Response;
> - REDFISH_PAYLOAD Payload;
> - CHAR8 *JsonText;
> - EFI_REST_JSON_STRUCTURE_HEADER *Header;
> + UINTN Index;
> + RedfishCS_char_Array *CharArrayBuffer;
> + RedfishCS_char_Array *PreArrayBuffer;
>
> - if (RedfishService == NULL || JsonStructProtocol == NULL ||
> IS_EMPTY_STRING (Uri) || SchemaInfo == NULL) {
> + if (Head == NULL || StringArray == NULL || ArraySize == 0) {
> 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);
> + PreArrayBuffer = NULL;
> + for (Index = 0; Index < ArraySize; Index++) {
> + CharArrayBuffer = AllocatePool (sizeof (RedfishCS_char_Array));
> + if (CharArrayBuffer == NULL) {
> + ASSERT (CharArrayBuffer != NULL);
> + continue;
> + }
>
> - JsonText = JsonDumpString (RedfishJsonInPayload (Payload),
> EDKII_JSON_COMPACT);
> - ASSERT (JsonText != NULL);
> + if (Index == 0) {
> + *Head = CharArrayBuffer;
> + }
>
> - //
> - // 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;
> + CharArrayBuffer->ArrayValue = StringArray[Index];
> + CharArrayBuffer->Next = NULL;
> + if (PreArrayBuffer != NULL) {
> + PreArrayBuffer->Next = CharArrayBuffer;
> + }
> + PreArrayBuffer = CharArrayBuffer;
> }
>
> - 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.
> + Create numeric array and append to arry node in Redfish JSON convert
> format.
>
> - @param[in] ConfigureLang Configure Language string.
> + @param[in,out] Head The head of string array.
> + @param[in] NumericArray Input numeric array.
> + @param[in] ArraySize The size of NumericArray.
>
> - @retval EFI_STRING Pointer to property name.
> - @retval NULL There is error.
> + @retval EFI_SUCCESS String array is created successfully.
> + @retval Others Error happens
>
> **/
> -EFI_STRING
> -GetPropertyFromConfigureLang (
> - IN EFI_STRING ConfigureLang
> +EFI_STATUS
> +AddRedfishNumericArray (
> + IN OUT RedfishCS_int64_Array **Head,
> + IN INT64 *NumericArray,
> + IN UINTN ArraySize
> )
> {
> - EFI_STRING Property;
> - UINTN Index;
> + UINTN Index;
> + RedfishCS_int64_Array *NumericArrayBuffer;
> + RedfishCS_int64_Array *PreArrayBuffer;
>
> - if (ConfigureLang == NULL) {
> - return NULL;
> + if (Head == NULL || NumericArray == NULL || ArraySize == 0) {
> + return EFI_INVALID_PARAMETER;
> }
>
> - Index = 0;
> - Property = ConfigureLang;
> -
> - while (ConfigureLang[Index] != '\0') {
> - if (ConfigureLang[Index] == L'/') {
> - Property = &ConfigureLang[Index];
> + PreArrayBuffer = NULL;
> + for (Index = 0; Index < ArraySize; Index++) {
> + NumericArrayBuffer = AllocatePool (sizeof (RedfishCS_int64_Array));
> + if (NumericArrayBuffer == NULL) {
> + ASSERT (NumericArrayBuffer != NULL);
> + continue;
> }
>
> - ++Index;
> + if (Index == 0) {
> + *Head = NumericArrayBuffer;
> + }
> + NumericArrayBuffer->ArrayValue = AllocatePool (sizeof
> (RedfishCS_int64));
> + if (NumericArrayBuffer->ArrayValue == NULL) {
> + ASSERT (NumericArrayBuffer->ArrayValue != NULL);
> + continue;
> + }
> + *NumericArrayBuffer->ArrayValue = NumericArray[Index];
> + NumericArrayBuffer->Next = NULL;
> + if (PreArrayBuffer != NULL) {
> + PreArrayBuffer->Next = NumericArrayBuffer;
> + }
> + PreArrayBuffer = NumericArrayBuffer;
> }
>
> - ++Property;
> -
> - return Property;
> + return EFI_SUCCESS;
> }
>
> /**
>
> - Get the property value in string type.
> + Create boolean array and append to arry node in Redfish JSON convert
> format.
>
> - @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.
> + @param[in,out] Head The head of string array.
> + @param[in] BooleanArray Input boolean array.
> + @param[in] ArraySize The size of BooleanArray.
>
> - @retval CHAR8* Pointer to the CHAR8 buffer.
> - @retval NULL There is error.
> + @retval EFI_SUCCESS String array is created successfully.
> + @retval Others Error happens
>
> **/
> -CHAR8 *
> -GetPropertyStringValue (
> - IN CHAR8 *Schema,
> - IN CHAR8 *Version,
> - IN EFI_STRING PropertyName,
> - IN EFI_STRING ConfigureLang
> +EFI_STATUS
> +AddRedfishBooleanArray (
> + IN OUT RedfishCS_bool_Array **Head,
> + IN BOOLEAN *BooleanArray,
> + IN UINTN ArraySize
> )
> {
> - EFI_STATUS Status;
> - EDKII_REDFISH_VALUE RedfishValue;
> - EFI_STRING ConfigureLangBuffer;
> - UINTN BufferSize;
> - CHAR8 *AsciiStringValue;
> + UINTN Index;
> + RedfishCS_bool_Array *BooleanArrayBuffer;
> + RedfishCS_bool_Array *PreArrayBuffer;
>
> - if (IS_EMPTY_STRING (Schema) || IS_EMPTY_STRING (Version) ||
> IS_EMPTY_STRING (ConfigureLang) || IS_EMPTY_STRING (PropertyName)) {
> - return NULL;
> + if (Head == NULL || BooleanArrayBuffer == NULL || ArraySize == 0) {
> + return EFI_INVALID_PARAMETER;
> }
>
> - //
> - // Configure Language buffer.
> - //
> - BufferSize = sizeof (CHAR16) * MAX_CONF_LANG_LEN;
> - ConfigureLangBuffer = AllocatePool (BufferSize);
> - if (ConfigureLangBuffer == NULL) {
> - return NULL;
> - }
> + PreArrayBuffer = NULL;
> + for (Index = 0; Index < ArraySize; Index++) {
> + BooleanArrayBuffer = AllocatePool (sizeof (RedfishCS_bool_Array));
> + if (BooleanArrayBuffer == NULL) {
> + ASSERT (BooleanArrayBuffer != NULL);
> + continue;
> + }
>
> - 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 (Index == 0) {
> + *Head = BooleanArrayBuffer;
> + }
>
> - 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;
> + BooleanArrayBuffer->ArrayValue = AllocatePool (sizeof
> (RedfishCS_bool));
> + if (BooleanArrayBuffer->ArrayValue == NULL) {
> + ASSERT (BooleanArrayBuffer->ArrayValue != NULL);
> + continue;
> + }
> + *BooleanArrayBuffer->ArrayValue = BooleanArray[Index];
> + BooleanArrayBuffer->Next = NULL;
> + if (PreArrayBuffer != NULL) {
> + PreArrayBuffer->Next = BooleanArrayBuffer;
> + }
> + PreArrayBuffer = BooleanArrayBuffer;
> }
>
> - AsciiStringValue = AllocateCopyPool (AsciiStrSize
> (RedfishValue.Value.Buffer), RedfishValue.Value.Buffer);
> - ASSERT (AsciiStringValue != NULL);
> -
> - return AsciiStringValue;
> + return EFI_SUCCESS;
> }
>
> /**
>
> - Get the property value in numeric type.
> + Check and see if value in Redfish string array are all the same as the one
> + from HII configuration.
>
> - @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.
> + @param[in] Head The head of string array.
> + @param[in] StringArray Input string array.
> + @param[in] ArraySize The size of StringArray.
>
> - @retval INT64* Pointer to the INT64 value.
> - @retval NULL There is error.
> + @retval TRUE All string in Redfish array are as same as string
> + in HII configuration array.
> + FALSE These two array are not identical.
>
> **/
> -INT64 *
> -GetPropertyNumericValue (
> - IN CHAR8 *Schema,
> - IN CHAR8 *Version,
> - IN EFI_STRING PropertyName,
> - IN EFI_STRING ConfigureLang
> +BOOLEAN
> +CompareRedfishStringArrayValues (
> + IN RedfishCS_char_Array *Head,
> + IN CHAR8 **StringArray,
> + IN UINTN ArraySize
> )
> {
> - EFI_STATUS Status;
> - EDKII_REDFISH_VALUE RedfishValue;
> - EFI_STRING ConfigureLangBuffer;
> - UINTN BufferSize;
> - INT64 *ResultValue;
> + UINTN Index;
> + RedfishCS_char_Array *CharArrayBuffer;
>
> - if (IS_EMPTY_STRING (Schema) || IS_EMPTY_STRING (Version) ||
> IS_EMPTY_STRING (ConfigureLang) || IS_EMPTY_STRING (PropertyName)) {
> - return NULL;
> + if (Head == NULL || StringArray == NULL || ArraySize == 0) {
> + return FALSE;
> }
>
> - //
> - // Configure Language buffer.
> - //
> - BufferSize = sizeof (CHAR16) * MAX_CONF_LANG_LEN;
> - ConfigureLangBuffer = AllocatePool (BufferSize);
> - if (ConfigureLangBuffer == NULL) {
> - return NULL;
> - }
> + CharArrayBuffer = Head;
> + Index = 0;
> + while (CharArrayBuffer != NULL && Index < ArraySize) {
>
> - 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 (AsciiStrCmp (StringArray[Index], CharArrayBuffer->ArrayValue) != 0) {
> + break;
> + }
>
> - 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;
> + Index++;
> + CharArrayBuffer = CharArrayBuffer->Next;
> }
>
> - ResultValue = AllocatePool (sizeof (INT64));
> - ASSERT (ResultValue != NULL);
> - if (ResultValue == NULL) {
> - return NULL;
> + if (CharArrayBuffer != NULL || Index < ArraySize) {
> + return FALSE;
> }
>
> - *ResultValue = RedfishValue.Value.Integer;
> -
> - return ResultValue;
> + return TRUE;
> }
>
> /**
>
> - Get the property value in Boolean type.
> + Check and see if value in Redfish numeric array are all the same as the one
> + from HII configuration.
>
> - @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.
> + @param[in] Head The head of Redfish CS numeraic array.
> + @param[in] NumericArray Input numeric array.
> + @param[in] ArraySize The size of NumericArray.
>
> - @retval BOOLEAN Boolean value returned by this property.
> + @retval TRUE All string in Redfish array are as same as integer
> + in HII configuration array.
> + FALSE These two array are not identical.
>
> **/
> -BOOLEAN *
> -GetPropertyBooleanValue (
> - IN CHAR8 *Schema,
> - IN CHAR8 *Version,
> - IN EFI_STRING PropertyName,
> - IN EFI_STRING ConfigureLang
> +BOOLEAN
> +CompareRedfishNumericArrayValues (
> + IN RedfishCS_int64_Array *Head,
> + IN INT64 *NumericArray,
> + IN UINTN ArraySize
> )
> {
> - 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;
> - }
> + UINTN Index;
> + RedfishCS_int64_Array *NumericArrayBuffer;
>
> - //
> - // Configure Language buffer.
> - //
> - BufferSize = sizeof (CHAR16) * MAX_CONF_LANG_LEN;
> - ConfigureLangBuffer = AllocatePool (BufferSize);
> - if (ConfigureLangBuffer == NULL) {
> - return NULL;
> + if (Head == NULL || NumericArray == NULL || ArraySize == 0) {
> + return FALSE;
> }
>
> - 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;
> - }
> + NumericArrayBuffer = Head;
> + Index = 0;
> + while (NumericArrayBuffer != NULL && Index < ArraySize) {
> + if (NumericArray[Index] != *NumericArrayBuffer->ArrayValue) {
> + break;
> + }
>
> - 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;
> + Index++;
> + NumericArrayBuffer = NumericArrayBuffer->Next;
> }
>
> - ResultValue = AllocatePool (sizeof (BOOLEAN));
> - ASSERT (ResultValue != NULL);
> - if (ResultValue == NULL) {
> - return NULL;
> + if (NumericArrayBuffer != NULL || Index < ArraySize) {
> + return FALSE;
> }
>
> - *ResultValue = RedfishValue.Value.Boolean;
> -
> - return ResultValue;
> + return TRUE;
> }
>
> /**
>
> - Check and see if we need to do provisioning for this property.
> + Check and see if value in Redfish boolean array are all the same as the one
> + from HII configuration.
>
> - @param[in] PropertyBuffer Pointer to property instance.
> - @param[in] ProvisionMode TRUE if we are in provision mode. FALSE
> otherwise.
> + @param[in] Head The head of Redfish CS boolean array.
> + @param[in] BooleanArray Input boolean array.
> + @param[in] ArraySize The size of BooleanArray.
>
> - @retval TRUE Provision is required.
> - @retval FALSE Provision is not required.
> + @retval TRUE All string in Redfish array are as same as integer
> + in HII configuration array.
> + FALSE These two array are not identical.
>
> **/
> BOOLEAN
> -PropertyChecker (
> - IN VOID *PropertyBuffer,
> - IN BOOLEAN ProvisionMode
> +CompareRedfishBooleanArrayValues (
> + IN RedfishCS_bool_Array *Head,
> + IN BOOLEAN *BooleanArray,
> + IN UINTN ArraySize
> )
> {
> - if (ProvisionMode && PropertyBuffer == NULL) {
> - return TRUE;
> + UINTN Index;
> + RedfishCS_bool_Array *BooleanArrayBuffer;
> +
> + if (Head == NULL || BooleanArray == NULL || ArraySize == 0) {
> + return FALSE;
> }
>
> - if (!ProvisionMode && PropertyBuffer != NULL) {
> - return TRUE;
> + BooleanArrayBuffer = Head;
> + Index = 0;
> + while (BooleanArrayBuffer != NULL && Index < ArraySize) {
> + if (BooleanArray[Index] != *BooleanArrayBuffer->ArrayValue) {
> + break;
> + }
> +
> + Index++;
> + BooleanArrayBuffer = BooleanArrayBuffer->Next;
> }
>
> - return FALSE;
> + if (BooleanArrayBuffer != NULL || Index < ArraySize) {
> + return FALSE;
> + }
> +
> + return TRUE;
> }
>
> /**
>
> - Check and see if we need to do provisioning for this two properties.
> + Check and see if any difference between two vague value set.
> + This is just a simple check.
>
> - @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.
> + @param[in] RedfishVagueKeyValuePtr The vague key value sets on
> Redfish service.
> + @param[in] RedfishVagueKeyValueNumber The numebr of vague key
> value sets
> + @param[in] ConfigVagueKeyValuePtr The vague configuration on
> platform.
> + @param[in] ConfigVagueKeyValueNumber The numebr of vague key
> value sets
>
> - @retval TRUE Provision is required.
> - @retval FALSE Provision is not required.
> + @retval TRUE All values are the same.
> + FALSE There is some difference.
>
> **/
> BOOLEAN
> -PropertyChecker2Parm (
> - IN VOID *PropertyBuffer1,
> - IN VOID *PropertyBuffer2,
> - IN BOOLEAN ProvisionMode
> +CompareRedfishPropertyVagueValues (
> + IN RedfishCS_EmptyProp_KeyValue *RedfishVagueKeyValuePtr,
> + IN UINT32 RedfishVagueKeyValueNumber,
> + IN RedfishCS_EmptyProp_KeyValue *ConfigVagueKeyValuePtr,
> + IN UINT32 ConfigVagueKeyValueNumber
> )
> -{
> - if (ProvisionMode && (PropertyBuffer1 == NULL || PropertyBuffer2 ==
> NULL)) {
> - return TRUE;
> - }
> + {
> + RedfishCS_EmptyProp_KeyValue *ThisConfigVagueKeyValuePtr;
> + RedfishCS_EmptyProp_KeyValue *ThisRedfishVagueKeyValuePtr;
>
> - if (!ProvisionMode && PropertyBuffer1 != NULL && PropertyBuffer2 !=
> NULL) {
> - return TRUE;
> + if (RedfishVagueKeyValueNumber != ConfigVagueKeyValueNumber) {
> + return FALSE;
> }
>
> - return FALSE;
> + ThisConfigVagueKeyValuePtr = ConfigVagueKeyValuePtr;
> + //
> + // Loop through all key/value on system.
> + //
> + while (ThisConfigVagueKeyValuePtr != NULL) {
> + ThisRedfishVagueKeyValuePtr = RedfishVagueKeyValuePtr;
> + //
> + // Loop through all key/value on Redfish service..
> + //
> + while (ThisRedfishVagueKeyValuePtr != NULL) {
> + if (AsciiStrCmp(ThisConfigVagueKeyValuePtr->KeyNamePtr,
> ThisRedfishVagueKeyValuePtr->KeyNamePtr) == 0) {
> + //
> + // Check the type of value.
> + //
> + if (ThisConfigVagueKeyValuePtr->Value->DataType !=
> ThisRedfishVagueKeyValuePtr->Value->DataType) {
> + return FALSE;
> + }
> + //
> + // Check the value.
> + //
> + if (ThisConfigVagueKeyValuePtr->Value->DataType ==
> RedfishCS_Vague_DataType_String) {
> + //
> + // Is the string identical?
> + //
> + if (AsciiStrCmp (ThisConfigVagueKeyValuePtr->Value-
> >DataValue.CharPtr,
> + ThisRedfishVagueKeyValuePtr->Value->DataValue.CharPtr
> + ) == 0) {
> + break;
> + } else{
> + return FALSE;
> + }
> + } else if (ThisConfigVagueKeyValuePtr->Value->DataType ==
> RedfishCS_Vague_DataType_Int64) {
> + if (*ThisConfigVagueKeyValuePtr->Value->DataValue.Int64Ptr ==
> *ThisRedfishVagueKeyValuePtr->Value->DataValue.Int64Ptr) {
> + break;
> + } else {
> + return FALSE;
> + }
> + } else if (ThisConfigVagueKeyValuePtr->Value->DataType ==
> RedfishCS_Vague_DataType_Bool) {
> + if ((UINT8)*ThisConfigVagueKeyValuePtr->Value->DataValue.BoolPtr
> == (UINT8)*ThisRedfishVagueKeyValuePtr->Value->DataValue.BoolPtr) {
> + break;
> + } else {
> + return FALSE;
> + }
> + } else {
> + return FALSE;
> + }
> + }
> + ThisRedfishVagueKeyValuePtr = ThisRedfishVagueKeyValuePtr-
> >NextKeyValuePtr;
> + };
> + if (ThisRedfishVagueKeyValuePtr == NULL) {
> + //
> + // No matched key name. Threat these two vague value set is different.
> + //
> + return FALSE;
> + }
> + ThisConfigVagueKeyValuePtr = ThisConfigVagueKeyValuePtr-
> >NextKeyValuePtr;
> + };
> + return TRUE;
> }
>
> /**
> diff --git
> a/RedfishClientPkg/Library/RedfishFeatureUtilityLib/RedfishFeatureUtilityLib
> .inf
> b/RedfishClientPkg/Library/RedfishFeatureUtilityLib/RedfishFeatureUtilityLib
> .inf
> index f9f283fdcc..84f338e680 100644
> ---
> a/RedfishClientPkg/Library/RedfishFeatureUtilityLib/RedfishFeatureUtilityLib
> .inf
> +++
> b/RedfishClientPkg/Library/RedfishFeatureUtilityLib/RedfishFeatureUtilityLib
> .inf
> @@ -1,6 +1,6 @@
> ## @file
> #
> -# (C) Copyright 2020-2021 Hewlett Packard Enterprise Development LP<BR>
> +# (C) Copyright 2020-2022 Hewlett Packard Enterprise Development
> LP<BR>
> #
> # SPDX-License-Identifier: BSD-2-Clause-Patent
> #
> @@ -27,6 +27,7 @@
> [Packages]
> MdePkg/MdePkg.dec
> MdeModulePkg/MdeModulePkg.dec
> + NetworkPkg/NetworkPkg.dec
> RedfishPkg/RedfishPkg.dec
> RedfishClientPkg/RedfishClientPkg.dec
>
> @@ -35,16 +36,25 @@
> BaseMemoryLib
> DebugLib
> MemoryAllocationLib
> - PrintLib
> RedfishLib
> RedfishPlatformConfigLib
> UefiLib
> UefiBootServicesTableLib
> UefiRuntimeServicesTableLib
> + PrintLib
> + HttpLib
>
> [Protocols]
> - gEdkIIRedfishETagProtocolGuid ## CONSUMED ##
> + gEdkIIRedfishETagProtocolGuid ## CONSUMED ##
> + gEdkIIRedfishConfigLangMapProtocolGuid ## CONSUMED ##
>
> [Pcd]
> - gEfiRedfishClientPkgTokenSpaceGuid.PcdMaxRedfishSchemaStringSize
> - gEfiRedfishClientPkgTokenSpaceGuid.PcdMaxRedfishSchemaVersionSize
> +
> +[Guids]
> +
> +[BuildOptions]
> + #
> + # NOTE: /wd4706 disables the following Visual Studio compiler warning in
> Jansson:
> + # "C4706: assignment within conditional expression"
> + #
> + MSFT:*_*_*_CC_FLAGS = /wd4706
> --
> 2.32.0.windows.2
next prev parent reply other threads:[~2022-07-28 3:14 UTC|newest]
Thread overview: 30+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-07-27 1:37 [edk2-staging][PATCH v3 00/15] Update RedfishClientpkg Nickle Wang
2022-07-27 1:37 ` [edk2-staging][PATCH v3 01/15] edk2-staging/RedfishClientPkg: Introduce Redfish event library Nickle Wang
2022-07-27 1:37 ` [edk2-staging][PATCH v3 02/15] edk2-staging/RedfishClientPkg: Introduce Redfish version library Nickle Wang
2022-07-27 1:37 ` [edk2-staging][PATCH v3 03/15] edk2-staging/RedfishClientPkg: Update Redfish Resource Config Protocol Nickle Wang
2022-07-27 1:37 ` [edk2-staging][PATCH v3 04/15] edk2-staging/RedfishClientPkg: Introduce Redfish resource config library Nickle Wang
2022-07-28 0:34 ` Chang, Abner
2022-07-27 1:37 ` [edk2-staging][PATCH v3 05/15] edk2-staging/RedfishClientPkg: Introduce resource identify library Nickle Wang
2022-07-27 15:48 ` Chang, Abner
2022-07-27 1:37 ` [edk2-staging][PATCH v3 06/15] edk2-staging/RedfishClientPkg: Introduce RedfishConfigLangMap driver Nickle Wang
2022-07-28 1:44 ` Chang, Abner
2022-07-27 1:37 ` [edk2-staging][PATCH v3 07/15] edk2-staging/RedfishClientPkg: Update ETag driver Nickle Wang
2022-07-28 1:45 ` Chang, Abner
2022-07-27 1:37 ` [edk2-staging][PATCH v3 08/15] edk2-staging/RedfishClientPkg: Update Redfish feature core driver Nickle Wang
2022-07-28 2:25 ` Chang, Abner
2022-07-27 1:37 ` [edk2-staging][PATCH v3 09/15] edk2-staging/RedfishClientPkg: Update RedfishLib Nickle Wang
2022-07-28 2:51 ` Chang, Abner
2022-07-27 1:37 ` [edk2-staging][PATCH v3 10/15] edk2-staging/RedfishClientPkg: Update Redfish feature utility library Nickle Wang
2022-07-28 3:13 ` Chang, Abner [this message]
2022-07-28 3:14 ` Chang, Abner
2022-07-27 1:37 ` [edk2-staging][PATCH v3 11/15] edk2-staging/RedfishClientPkg: Rename RedfishMemoryCollection driver Nickle Wang
2022-07-28 3:41 ` Chang, Abner
2022-07-27 1:37 ` [edk2-staging][PATCH v3 12/15] edk2-staging/RedfishClientPkg: Rename Memory feature driver Nickle Wang
2022-07-28 3:43 ` Chang, Abner
2022-07-27 1:38 ` [edk2-staging][PATCH v3 13/15] edk2-staging/RedfishClientPkg: Introduce Computer System collection driver Nickle Wang
2022-07-28 3:46 ` Chang, Abner
2022-07-27 1:38 ` [edk2-staging][PATCH v3 14/15] edk2-staging/RedfishClientPkg: Introduce Computer System feature driver Nickle Wang
2022-07-28 3:48 ` Chang, Abner
2022-07-27 1:38 ` [edk2-staging][PATCH v3 15/15] edk2-staging/RedfishClientPkg: Introduce Bios " Nickle Wang
2022-07-28 3:48 ` Chang, Abner
2022-07-29 0:29 ` Nickle Wang
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=MN2PR12MB396684CB6FB8A7D83DAA9026EA969@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