From nobody Fri May 3 17:35:24 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) client-ip=66.175.222.108; envelope-from=bounce+27952+82779+1787277+3901457@groups.io; helo=mail02.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+82779+1787277+3901457@groups.io; dmarc=fail(p=none dis=none) header.from=hpe.com ARC-Seal: i=1; a=rsa-sha256; t=1635384750; cv=none; d=zohomail.com; s=zohoarc; b=A9lo6z9J+DZt/91TPuKKIG3/wXLayOPhop90DLVq5E2o/+CoRkuN5p5UmrKNCjbMQPEwf+ljerFH9mjQeIq49MGwTMsahLoMbCv2Mob1S46h5oCK17asWOBjJDG7FlZlqB3kcxLl0/r7lZbkH+hyF1IMVyO7BdI8MxdOsO8jCp8= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1635384750; h=Content-Transfer-Encoding:Cc:Date:From:List-Subscribe:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:Sender:Subject:To; bh=UWeBhzuKiFiGlXPj+Es2WMUuRVpoj0glGf6OhDN8Uok=; b=Je5o2w79RNBEeBnQ71TBX8oUx9tRu1+53URABf7NBL3aa7Xpqty+O2t3MbMX/AtmNOlAQvX4XZE5HxsV5ik7r8ji6d85llvbskbIK4sykgM7+3QdWFMhY2v39pq/ECoIDFXWHXJaZSPD9Ao4rDDpCvZ+C1jvQ+QpEFq+G7jTnss= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+82779+1787277+3901457@groups.io; dmarc=fail header.from= (p=none dis=none) Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 1635384750212111.74859789421976; Wed, 27 Oct 2021 18:32:30 -0700 (PDT) Return-Path: X-Received: by 127.0.0.2 with SMTP id QwYmYY1788612xlb49TjdoR9; Wed, 27 Oct 2021 18:32:29 -0700 X-Received: from mx0a-002e3701.pphosted.com (mx0a-002e3701.pphosted.com [148.163.147.86]) by mx.groups.io with SMTP id smtpd.web12.5530.1635384745411221056 for ; Wed, 27 Oct 2021 18:32:29 -0700 X-Received: from pps.filterd (m0148663.ppops.net [127.0.0.1]) by mx0a-002e3701.pphosted.com (8.16.1.2/8.16.1.2) with SMTP id 19S16QEE014998; Thu, 28 Oct 2021 01:32:19 GMT X-Received: from g9t5009.houston.hpe.com (g9t5009.houston.hpe.com [15.241.48.73]) by mx0a-002e3701.pphosted.com with ESMTP id 3bxyx593g9-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Thu, 28 Oct 2021 01:32:19 +0000 X-Received: from g4t3433.houston.hpecorp.net (g4t3433.houston.hpecorp.net [16.208.49.245]) by g9t5009.houston.hpe.com (Postfix) with ESMTP id 40F2C5C; Thu, 28 Oct 2021 01:32:18 +0000 (UTC) X-Received: from SAC2XFT1JT.asiapacific.hpqcorp.net (unknown [10.43.62.133]) by g4t3433.houston.hpecorp.net (Postfix) with ESMTP id 366E745; Thu, 28 Oct 2021 01:32:17 +0000 (UTC) From: "Abner Chang" To: devel@edk2.groups.io Cc: nickle.wang@hpe.com, Liming Gao Subject: [edk2-devel] [PATCH] edk2-staging/RedfishClientPkg: Add Redfish Feature Utility library Date: Thu, 28 Oct 2021 09:32:16 +0800 Message-Id: <20211028013216.48552-1-abner.chang@hpe.com> MIME-Version: 1.0 X-Proofpoint-ORIG-GUID: MdVJLGy7X1Md0StHZPqmtGmuyBHNpyRX X-Proofpoint-GUID: MdVJLGy7X1Md0StHZPqmtGmuyBHNpyRX X-HPE-SCL: -1 Precedence: Bulk List-Unsubscribe: List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,abner.chang@hpe.com X-Gm-Message-State: mIOSkJBzdcDpb8RxX8qA0umCx1787277AA= Content-Transfer-Encoding: quoted-printable DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1635384749; bh=IyM3y6OwmovDpCYx2ihWaxC7enYFu6t+LhoUeYCKFaI=; h=Cc:Date:From:Reply-To:Subject:To; b=is5cmry0/swjTJbXvCEhjqd+290xrlcGfchBfZ4ZHHFqiFEw963SHdiRENyg/3cQPCx b/OMEajlmM02AasYkLEy43uEtImEGFeO9fhOve5wwz3oUNN4smJN3QKp2Q2UcPXF5sCPu dubTQmA/pUCFczplSuUqVVju6u5F8/J9gfM= X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1635384751077100002 Content-Type: text/plain; charset="utf-8" This is the helper library for EDKII Redfish feature drivers to manipulate Redfish properties. Signed-off-by: Nickle Wang Cc: Abner Chang Cc: Liming Gao --- RedfishClientPkg/RedfishClientPkg.dec | 3 + RedfishClientPkg/RedfishClientLibs.dsc.inc | 3 + RedfishClientPkg/RedfishClientPkg.dsc | 2 + .../RedfishFeatureUtilityLib.inf | 50 + .../Library/RedfishFeatureUtilityLib.h | 471 +++++ .../RedfishFeatureUtilityInternal.h | 45 + .../RedfishFeatureUtilityLib.c | 1515 +++++++++++++++++ 7 files changed, 2089 insertions(+) create mode 100644 RedfishClientPkg/Library/RedfishFeatureUtilityLib/Redfi= shFeatureUtilityLib.inf create mode 100644 RedfishClientPkg/Include/Library/RedfishFeatureUtilityL= ib.h create mode 100644 RedfishClientPkg/Library/RedfishFeatureUtilityLib/Redfi= shFeatureUtilityInternal.h create mode 100644 RedfishClientPkg/Library/RedfishFeatureUtilityLib/Redfi= shFeatureUtilityLib.c diff --git a/RedfishClientPkg/RedfishClientPkg.dec b/RedfishClientPkg/Redfi= shClientPkg.dec index f0fe3269c02..b965f915a84 100644 --- a/RedfishClientPkg/RedfishClientPkg.dec +++ b/RedfishClientPkg/RedfishClientPkg.dec @@ -19,6 +19,9 @@ PrivateInclude # Private header files PrivateInclude/Crt # Private header files for C RTL. =20 +[LibraryClasses] + RedfishFeatureUtilityLib|Include/Library/RedfishFeatureUtilityLib.h + [Protocols] ## Include/Protocol/EdkIIRedfishFeature.h gEdkIIRedfishFeatureProtocolGuid =3D { 0x785CC694, 0x4930, 0xEFBF= , { 0x2A, 0xCB, 0xA4, 0xB6, 0xA1, 0xCC, 0xAA, 0x34 } } diff --git a/RedfishClientPkg/RedfishClientLibs.dsc.inc b/RedfishClientPkg/= RedfishClientLibs.dsc.inc index 7e313ae5c74..a5ae73cac7f 100644 --- a/RedfishClientPkg/RedfishClientLibs.dsc.inc +++ b/RedfishClientPkg/RedfishClientLibs.dsc.inc @@ -14,3 +14,6 @@ !include RedfishClientPkg/RedfishJsonStructureLib.dsc.inc !endif =20 + RedfishFeatureUtilityLib|RedfishClientPkg/Library/RedfishFeatureUtilityL= ib/RedfishFeatureUtilityLib.inf + RedfishPlatformConfigLib|RedfishPkg/Library/RedfishPlatformConfigLib/Red= fishPlatformConfigLib.inf + diff --git a/RedfishClientPkg/RedfishClientPkg.dsc b/RedfishClientPkg/Redfi= shClientPkg.dsc index adb50cec21f..00a963eaff1 100644 --- a/RedfishClientPkg/RedfishClientPkg.dsc +++ b/RedfishClientPkg/RedfishClientPkg.dsc @@ -47,4 +47,6 @@ =20 [Components] =20 + RedfishClientPkg/Library/RedfishFeatureUtilityLib/RedfishFeatureUtilityL= ib.inf + !include RedfishClientPkg/RedfishClient.dsc.inc diff --git a/RedfishClientPkg/Library/RedfishFeatureUtilityLib/RedfishFeatu= reUtilityLib.inf b/RedfishClientPkg/Library/RedfishFeatureUtilityLib/Redfis= hFeatureUtilityLib.inf new file mode 100644 index 00000000000..f9f283fdcca --- /dev/null +++ b/RedfishClientPkg/Library/RedfishFeatureUtilityLib/RedfishFeatureUtili= tyLib.inf @@ -0,0 +1,50 @@ +## @file +# +# (C) Copyright 2020-2021 Hewlett Packard Enterprise Development LP
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION =3D 0x00010006 + BASE_NAME =3D RedfishFeatureUtilityLib + FILE_GUID =3D 8BBE1212-A4BF-4ECA-B89B-8F85F83CC9B7 + MODULE_TYPE =3D DXE_DRIVER + VERSION_STRING =3D 1.0 + LIBRARY_CLASS =3D RedfishFeatureUtilityLib| DXE_DRIVER = DXE_RUNTIME_DRIVER UEFI_APPLICATION UEFI_DRIVER + CONSTRUCTOR =3D RedfishFeatureUtilityLibConstructor + DESTRUCTOR =3D RedfishFeatureUtilityLibDestructor + +# +# VALID_ARCHITECTURES =3D IA32 X64 EBC +# + +[Sources] + RedfishFeatureUtilityLib.c + RedfishFeatureUtilityInternal.h + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + RedfishPkg/RedfishPkg.dec + RedfishClientPkg/RedfishClientPkg.dec + +[LibraryClasses] + BaseLib + BaseMemoryLib + DebugLib + MemoryAllocationLib + PrintLib + RedfishLib + RedfishPlatformConfigLib + UefiLib + UefiBootServicesTableLib + UefiRuntimeServicesTableLib + +[Protocols] + gEdkIIRedfishETagProtocolGuid ## CONSUMED ## + +[Pcd] + gEfiRedfishClientPkgTokenSpaceGuid.PcdMaxRedfishSchemaStringSize + gEfiRedfishClientPkgTokenSpaceGuid.PcdMaxRedfishSchemaVersionSize diff --git a/RedfishClientPkg/Include/Library/RedfishFeatureUtilityLib.h b/= RedfishClientPkg/Include/Library/RedfishFeatureUtilityLib.h new file mode 100644 index 00000000000..50ff82c70f4 --- /dev/null +++ b/RedfishClientPkg/Include/Library/RedfishFeatureUtilityLib.h @@ -0,0 +1,471 @@ +/** @file + This file defines the Redfish Feature Utility Library interface. + + (C) Copyright 2021 Hewlett Packard Enterprise Development LP
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef REDFISH_FEATURE_UTILITY_LIB_H_ +#define REDFISH_FEATURE_UTILITY_LIB_H_ + +#include +#include + +// +// Definition of REDFISH_FEATURE_ARRAY_TYPE_CONFIG_LANG +// +typedef struct { + UINTN Index; + EFI_STRING ConfigureLang; +} REDFISH_FEATURE_ARRAY_TYPE_CONFIG_LANG; + +// +// Definition of REDFISH_FEATURE_ARRAY_TYPE_CONFIG_LANG_LIST +// +typedef struct { + UINTN Count; + REDFISH_FEATURE_ARRAY_TYPE_CONFIG_LANG *List; +} REDFISH_FEATURE_ARRAY_TYPE_CONFIG_LANG_LIST; + +/** + + Read redfish resource by given resource path. + + @param[in] Service Redfish srvice instacne to make query. + @param[in] ResourcePath Target resource path. + @param[out] Response HTTP response from redfish service. + + @retval EFI_SUCCESS Resrouce is returned successfully. + @retval Others Errors occur. + +**/ +EFI_STATUS +GetResourceByPath ( + IN REDFISH_SERVICE *Service, + IN CHAR8 *ResourcePath, + OUT REDFISH_RESPONSE *Response + ); + +/** + + Search HII database with given Configure Language pattern. Data is handl= ed and + returned in array. + + @param[in] Schema The schema to search. + @param[in] Version The schema version. + @param[in] Pattern Configure Language pattern to sear= ch. + @param[out] UnifiedConfigureLangList The data returned by HII database. + + @retval EFI_SUCCESS Data is found and returned. + @retval Others Errors occur. + +**/ +EFI_STATUS +RedfishFeatureGetUnifiedArrayTypeConfigureLang ( + IN CHAR8 *Schema, + IN CHAR8 *Version, + IN EFI_STRING Pattern, + OUT REDFISH_FEATURE_ARRAY_TYPE_CONFIG_LANG_LIST *UnifiedConfigureLan= gList + ); + +/** + + Get array key by parsing the URI. + + @param[in] Uri URI with array key. + @param[out] ArrayKey Array key in given URI string. + + @retval EFI_SUCCESS Array key is found. + @retval Others Errors occur. + +**/ +EFI_STATUS +GetArraykeyFromUri ( + IN CHAR8 *Uri, + OUT CHAR8 **ArrayKey + ); + +/** + + Keep configure language with given key in UEFI variable. + + @param[in] Schema Schema name. + @param[in] Version Schema version. + @param[in] Key Key string. + @param[in] ConfigureLangIndex Index value. + + @retval EFI_SUCCESS Data is saved in UEFI variable. + @retval Others Errors occur. + +**/ +EFI_STATUS +SetConfigureLangWithkey ( + IN CHAR8 *Schema, + IN CHAR8 *Version, + IN CHAR8 *Key, + IN UINTN ConfigureLangIndex + ); + +/** + + Find configure language with input key string. + + @param[in] Schema Schema name. + @param[in] Version Schema version. + @param[in] Property Property name. + @param[in] Key Key string. + + @retval CHAR16 * Corresponding configure langauge + @retval NULL No configure language is found + +**/ +CHAR16 * +GetConfigureLangByKey ( + IN CHAR8 *Schema, + IN CHAR8 *Version, + IN CHAR8 *Property, + IN CHAR8 *Key + ); + +/** + + Convert HII string value to string value in JSON format. + + @param[in] HiiStringValue String in HII format. + + @retval CHAR8 * String in JSON format. + @retval NULL Errors occur. + +**/ +CHAR8 * +ConvertHiiStringValueToJsonStringValue ( + IN EFI_STRING HiiStringValue + ); + +/** + + Apply property value to UEFI HII database in string type. + + @param[in] Schema Property schema. + @param[in] Version Property schema version. + @param[in] ConfigureLang Configure language refers to this property. + @param[in] FeatureValue New value to set. + + @retval EFI_SUCCESS New value is applied successfully. + @retval Others Errors occur. + +**/ +EFI_STATUS +ApplyFeatureSettingsStringType ( + IN CHAR8 *Schema, + IN CHAR8 *Version, + IN EFI_STRING ConfigureLang, + IN CHAR8 *FeatureValue + ); + +/** + + Apply property value to UEFI HII database in numric type. + + @param[in] Schema Property schema. + @param[in] Version Property schema version. + @param[in] ConfigureLang Configure language refers to this property. + @param[in] FeatureValue New value to set. + + @retval EFI_SUCCESS New value is applied successfully. + @retval Others Errors occur. + +**/ +EFI_STATUS +ApplyFeatureSettingsNumericType ( + IN CHAR8 *Schema, + IN CHAR8 *Version, + IN EFI_STRING ConfigureLang, + IN INTN FeatureValue + ); + +/** + + Apply property value to UEFI HII database in boolean type. + + @param[in] Schema Property schema. + @param[in] Version Property schema version. + @param[in] ConfigureLang Configure language refers to this property. + @param[in] FeatureValue New value to set. + + @retval EFI_SUCCESS New value is applied successfully. + @retval Others Errors occur. + +**/ +EFI_STATUS +ApplyFeatureSettingsBooleanType ( + IN CHAR8 *Schema, + IN CHAR8 *Version, + IN EFI_STRING ConfigureLang, + IN BOOLEAN FeatureValue + ); + +/** + + Create HTTP payload and send them to redfish service with POST method. + + @param[in] Service Redfish service. + @param[in] TargetPayload Target payload + @param[in] Json Data in JSON format. + @param[out] Location Returned location string from Redfish servic= e. + @param[out] Etag Returned ETAG string from Redfish service. + + @retval EFI_SUCCESS Data is sent to redfish service successfully. + @retval Others Errors occur. + +**/ +EFI_STATUS +CreatePayloadToPostResource ( + IN REDFISH_SERVICE *Service, + IN REDFISH_PAYLOAD *TargetPayload, + IN CHAR8 *Json, + OUT CHAR8 **Location, + OUT CHAR8 **Etag + ); + +/** + + Create HTTP payload and send them to redfish service with PATCH method. + + @param[in] Service Redfish service. + @param[in] TargetPayload Target payload + @param[in] Json Data in JSON format. + @param[out] Etag Returned ETAG string from Redfish service. + + @retval EFI_SUCCESS Data is sent to redfish service successfully. + @retval Others Errors occur. + +**/ +EFI_STATUS +CreatePayloadToPatchResource ( + IN REDFISH_SERVICE *Service, + IN REDFISH_PAYLOAD *TargetPayload, + IN CHAR8 *Json, + OUT CHAR8 **Etag + ); + +/** + + Find Redfish Resource Config Protocol that supports given schema and ver= sion. + + @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 proto= col + @retval NULL No protocol foun= d. + +**/ +EDKII_REDFISH_RESOURCE_CONFIG_PROTOCOL * +GetRedfishResourceConfigProtocol ( + IN CHAR8 *Schema, + IN CHAR8 *Major, + IN CHAR8 *Minor, + IN CHAR8 *Errata + ); + +/** + + Get supported schema list by given specify schema name. + + @param[in] Schema Schema type name. + @param[out] SchemaInfo Returned schema information. + + @retval EFI_SUCCESS Schema information is returned successfu= lly. + @retval Others Errors occur. + +**/ +EFI_STATUS +GetSupportedSchemaVersion ( + IN CHAR8 *Schema, + OUT REDFISH_SCHEMA_INFO *SchemaInfo + ); + +/** + + Return system root path + + @retval NULL Can not find system root path. + @retval Other System root path is returned. + +**/ +CHAR8 * +RedfishGetSystemRootPath ( + VOID + ); + +/** + + Get schema information by given protocol and service instance. + + @param[in] RedfishService Pointer to Redfish service instance. + @param[in] JsonStructProtocol Json Structure protocol instance. + @param[in] Uri Target URI. + @param[out] SchemaInfo Returned schema information. + + @retval EFI_SUCCESS Schema information is returned successfu= lly. + @retval Others Errors occur. + +**/ +EFI_STATUS +GetRedfishSchemaInfo ( + IN REDFISH_SERVICE *RedfishService, + IN EFI_REST_JSON_STRUCTURE_PROTOCOL *JsonStructProtocol, + IN CHAR8 *Uri, + OUT REDFISH_SCHEMA_INFO *SchemaInfo + ); + +/** + + Get the property name by given Configure Langauge. + + @param[in] ConfigureLang Configure Language string. + + @retval EFI_STRING Pointer to property name. + @retval NULL There is error. + +**/ +EFI_STRING +GetPropertyFromConfigureLang ( + IN EFI_STRING ConfigureLang + ); + +/** + + Get the property value in string type. + + @param[in] Schema Schema of this property. + @param[in] Version Schema version. + @param[in] PropertyName Property name. + @param[in] ConfigureLang Configure Language of this property. + + @retval CHAR8* Pointer to the CHAR8 buffer. + @retval NULL There is error. + +**/ +CHAR8 * +GetPropertyStringValue ( + IN CHAR8 *Schema, + IN CHAR8 *Version, + IN EFI_STRING PropertyName, + IN EFI_STRING ConfigureLang + ); + +/** + + Get the property value in numeric type. + + @param[in] Schema Schema of this property. + @param[in] Version Schema version. + @param[in] PropertyName Property name. + @param[in] ConfigureLang Configure Language of this property. + + @retval INT64* Pointer to the INT64 value. + @retval NULL There is error. + +**/ +INT64 * +GetPropertyNumericValue ( + IN CHAR8 *Schema, + IN CHAR8 *Version, + IN EFI_STRING PropertyName, + IN EFI_STRING ConfigureLang + ); + +/** + + Get the property value in Boolean type. + + @param[in] Schema Schema of this property. + @param[in] Version Schema version. + @param[in] PropertyName Property name. + @param[in] ConfigureLang Configure Language of this property. + + @retval BOOLEAN Boolean value returned by this property. + +**/ +BOOLEAN * +GetPropertyBooleanValue ( + IN CHAR8 *Schema, + IN CHAR8 *Version, + IN EFI_STRING PropertyName, + IN EFI_STRING ConfigureLang + ); + +/** + + Check and see if we need to do provisioning for this property. + + @param[in] PropertyBuffer Pointer to property instance. + @param[in] ProvisionMode TRUE if we are in provision mode. FALSE oth= erwise. + + @retval TRUE Provision is required. + @retval FALSE Provision is not required. + +**/ +BOOLEAN +PropertyChecker ( + IN VOID *PropertyBuffer, + IN BOOLEAN ProvisionMode + ); + +/** + + Check and see if we need to do provisioning for this two properties. + + @param[in] PropertyBuffer1 Pointer to property instance 1. + @param[in] PropertyBuffer2 Pointer to property instance 2. + @param[in] ProvisionMode TRUE if we are in provision mode. FALSE ot= herwise. + + @retval TRUE Provision is required. + @retval FALSE Provision is not required. + +**/ +BOOLEAN +PropertyChecker2Parm ( + IN VOID *PropertyBuffer1, + IN VOID *PropertyBuffer2, + IN BOOLEAN ProvisionMode + ); + +/** + + Keep ETAG string and URI string in database. + + @param[in] EtagStr ETAG string. + @param[in] Uri URI string. + + @retval EFI_SUCCESS ETAG and URI are applied successfully. + @retval Others Errors occur. + +**/ +EFI_STATUS +SetEtagWithUri ( + IN CHAR8 *EtagStr, + IN CHAR8 *Uri + ); + +/** + + Find ETAG string that refers to given URI. + + @param[in] Uri Target URI string. + + @retval CHAR8 * ETAG string + @retval NULL No ETAG is found. + +**/ +CHAR8 * +GetEtagWithUri ( + IN CHAR8 *Uri + ); + +#endif diff --git a/RedfishClientPkg/Library/RedfishFeatureUtilityLib/RedfishFeatu= reUtilityInternal.h b/RedfishClientPkg/Library/RedfishFeatureUtilityLib/Red= fishFeatureUtilityInternal.h new file mode 100644 index 00000000000..b8f4df7bcdc --- /dev/null +++ b/RedfishClientPkg/Library/RedfishFeatureUtilityLib/RedfishFeatureUtili= tyInternal.h @@ -0,0 +1,45 @@ +/** @file + Common header file for RedfishFeatureUtilityLib driver. + + (C) Copyright 2020-2021 Hewlett Packard Enterprise Development LP
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef REDFISH_FEATURE_INTERNAL_H_ +#define REDFISH_FEATURE_INTERNAL_H_ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +#define INDEX_VARIABLE_SIZE 64 +#define INDEX_STRING_SIZE 16 +#define IS_EMPTY_STRING(a) (a =3D=3D NULL || a[0] =3D=3D '\0') +#define INDEX_STRING L"{%d}" +#define SCHEMA_NAME_PREFIX_OFFSET 15 // x-uefi-redfish- +#define REDFISH_SYSTEM_ROOT_PATH "/v1/Systems[UUID~%g]" +#define MAX_CONF_LANG_LEN 128 + +#define BIOS_CONFIG_TO_REDFISH_REDPATH_ARRAY_START_SIGNATURE L"{" +#define BIOS_CONFIG_TO_REDFISH_REDPATH_ARRAY_END_SIGNATURE L"}" +#define BIOS_CONFIG_TO_REDFISH_REDPATH_POOL_SIZE 64 + +#endif diff --git a/RedfishClientPkg/Library/RedfishFeatureUtilityLib/RedfishFeatu= reUtilityLib.c b/RedfishClientPkg/Library/RedfishFeatureUtilityLib/RedfishF= eatureUtilityLib.c new file mode 100644 index 00000000000..cf8696e5f07 --- /dev/null +++ b/RedfishClientPkg/Library/RedfishFeatureUtilityLib/RedfishFeatureUtili= tyLib.c @@ -0,0 +1,1515 @@ +/** @file + Redfish feature utility library implementation + + (C) Copyright 2020-2021 Hewlett Packard Enterprise Development LP
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "RedfishFeatureUtilityInternal.h" + +EDKII_REDFISH_ETAG_PROTOCOL *mEtagProtocol; + +/** + + Get array key by parsing the URI. + + @param[in] Uri URI with array key. + @param[out] ArrayKey Array key in given URI string. + + @retval EFI_SUCCESS Array key is found. + @retval Others Errors occur. + +**/ +EFI_STATUS +GetArraykeyFromUri ( + IN CHAR8 *Uri, + OUT CHAR8 **ArrayKey + ) +{ + CHAR8 *LeftBracket; + UINTN Index; + + if (IS_EMPTY_STRING (Uri) || ArrayKey =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + + *ArrayKey =3D NULL; + + // + // Loop through Uri and find last '[' + // + LeftBracket =3D NULL; + for (Index =3D 0; Uri[Index] !=3D '\0'; Index++) { + if (Uri[Index] =3D=3D '[') { + LeftBracket =3D &Uri[Index]; + } + } + + if (LeftBracket =3D=3D NULL) { + return EFI_NOT_FOUND; + } + + // + // skip '/' + // + ++LeftBracket; + + *ArrayKey =3D AllocateCopyPool (AsciiStrSize (LeftBracket), LeftBracket); + if (*ArrayKey =3D=3D NULL) { + return EFI_OUT_OF_RESOURCES; + } + + // + // remove ']' + // + *(*ArrayKey + AsciiStrLen (*ArrayKey) - 1) =3D '\0'; + + return EFI_SUCCESS; +} + +/** + + Keep configure language with given key in UEFI variable. + + @param[in] Schema Schema name. + @param[in] Version Schema version. + @param[in] Key Key string. + @param[in] ConfigureLangIndex Index value. + + @retval EFI_SUCCESS Data is saved in UEFI variable. + @retval Others Errors occur. + +**/ +EFI_STATUS +SetConfigureLangWithkey ( + IN CHAR8 *Schema, + IN CHAR8 *Version, + IN CHAR8 *Key, + IN UINTN ConfigureLangIndex + ) +{ + CHAR16 IndexString[INDEX_STRING_SIZE]; + CHAR16 VarName[INDEX_VARIABLE_SIZE]; + CHAR16 *VarData; + EFI_STATUS Status; + // + // Variable content. + // + UnicodeSPrint (IndexString, sizeof (IndexString), INDEX_STRING, Configur= eLangIndex); + + // + // Variable name. + // + UnicodeSPrint (VarName, sizeof (VarName), L"%a_%a_%a", Schema, Version, = Key); + + // + // Check if it exists already. + // + Status =3D GetVariable2 ( + VarName, + &gEfiCallerIdGuid, + (VOID *)&VarData, + NULL + ); + if (!EFI_ERROR (Status)) { + DEBUG ((DEBUG_INFO, "%a, remove stale data: %s\n", __FUNCTION__, VarDa= ta)); + FreePool (VarData); + gRT->SetVariable (VarName, &gEfiCallerIdGuid, VARIABLE_ATTRIBUTE_NV_BS= , 0, NULL); + } + + return gRT->SetVariable (VarName, &gEfiCallerIdGuid, VARIABLE_ATTRIBUTE_= NV_BS, StrSize (IndexString), (VOID *)&IndexString); +} + +/** + + Find configure language with input key string. + + @param[in] Schema Schema name. + @param[in] Version Schema version. + @param[in] Property Property name. + @param[in] Key Key string. + + @retval CHAR16 * Corresponding configure langauge + @retval NULL No configure language is found + +**/ +CHAR16 * +GetConfigureLangByKey ( + IN CHAR8 *Schema, + IN CHAR8 *Version, + IN CHAR8 *Property, OPTIONAL + IN CHAR8 *Key + ) +{ + EFI_STATUS Status; + CHAR16 VariableName[64]; + UINTN VariableSize; + CHAR16 *CollectionIndex; + CHAR16 *ConfigureLang; + UINTN ConfigureLangLen; + + if (Schema =3D=3D NULL || Version =3D=3D NULL || Key =3D=3D NULL) { + return NULL; + } + + CollectionIndex =3D NULL; + ConfigureLang =3D NULL; + + UnicodeSPrint (VariableName, 64, L"%a_%a_%a", Schema, Version, Key); + + Status =3D GetVariable2 ( + VariableName, + &gEfiCallerIdGuid, + (VOID *)&CollectionIndex, + &VariableSize + ); + if (EFI_ERROR (Status)) { + return NULL; + } + + ConfigureLangLen =3D AsciiStrLen (Schema) + StrLen (CollectionIndex) + (= Property =3D=3D NULL ? 0 : AsciiStrLen (Property)) + 3 + 1; + ConfigureLang =3D AllocatePool (sizeof (CHAR16) * ConfigureLangLen); + ASSERT (ConfigureLang); + + if (Property !=3D NULL) { + UnicodeSPrint (ConfigureLang, sizeof (CHAR16) * ConfigureLangLen, L"/%= a/%s/%a", Schema, CollectionIndex, Property); + } else { + UnicodeSPrint (ConfigureLang, sizeof (CHAR16) * ConfigureLangLen, L"/%= a/%s", Schema, CollectionIndex); + } + + FreePool (CollectionIndex); + + return ConfigureLang; +} + +/** + + Keep ETAG string and URI string in database. + + @param[in] EtagStr ETAG string. + @param[in] Uri URI string. + + @retval EFI_SUCCESS ETAG and URI are applied successfully. + @retval Others Errors occur. + +**/ +EFI_STATUS +SetEtagWithUri ( + IN CHAR8 *EtagStr, + IN CHAR8 *Uri + ) +{ + EFI_STATUS Status; + + if (IS_EMPTY_STRING (EtagStr) || IS_EMPTY_STRING (Uri)) { + return EFI_INVALID_PARAMETER; + } + + if (mEtagProtocol =3D=3D NULL) { + Status =3D gBS->LocateProtocol ( + &gEdkIIRedfishETagProtocolGuid, + NULL, + (VOID **)&mEtagProtocol + ); + if (EFI_ERROR (Status)) { + return Status; + } + } + + mEtagProtocol->Set (mEtagProtocol, Uri, EtagStr); + mEtagProtocol->Flush (mEtagProtocol); + + return EFI_SUCCESS; +} + +/** + + Find ETAG string that refers to given URI. + + @param[in] Uri Target URI string. + + @retval CHAR8 * ETAG string + @retval NULL No ETAG is found. + +**/ +CHAR8 * +GetEtagWithUri ( + IN CHAR8 *Uri + ) +{ + EFI_STATUS Status; + CHAR8 *EtagStr; + + if (IS_EMPTY_STRING (Uri)) { + return NULL; + } + + if (mEtagProtocol =3D=3D NULL) { + Status =3D gBS->LocateProtocol ( + &gEdkIIRedfishETagProtocolGuid, + NULL, + (VOID **)&mEtagProtocol + ); + if (EFI_ERROR (Status)) { + return NULL; + } + } + + Status =3D mEtagProtocol->Get (mEtagProtocol, Uri, &EtagStr); + if (EFI_ERROR (Status)) { + return NULL; + } + + return EtagStr; +} + +/** + + Convert HII string value to string value in JSON format. + + @param[in] HiiStringValue String in HII format. + + @retval CHAR8 * String in JSON format. + @retval NULL Errors occur. + +**/ +CHAR8 * +ConvertHiiStringValueToJsonStringValue ( + IN EFI_STRING HiiStringValue + ) +{ + CHAR8 *JsonValue; + UINTN JsonValueSize; + + if (IS_EMPTY_STRING (HiiStringValue)) { + return NULL; + } + + JsonValueSize =3D StrLen (HiiStringValue) + 1; + JsonValue =3D AllocatePool (JsonValueSize); + UnicodeStrToAsciiStrS (HiiStringValue, JsonValue, JsonValueSize); + + return JsonValue; +} + +/** + + Apply property value to UEFI HII database in string type. + + @param[in] Schema Property schema. + @param[in] Version Property schema version. + @param[in] ConfigureLang Configure language refers to this property. + @param[in] FeatureValue New value to set. + + @retval EFI_SUCCESS New value is applied successfully. + @retval Others Errors occur. + +**/ +EFI_STATUS +ApplyFeatureSettingsStringType ( + IN CHAR8 *Schema, + IN CHAR8 *Version, + IN EFI_STRING ConfigureLang, + IN CHAR8 *FeatureValue + ) +{ + EFI_STATUS Status; + EDKII_REDFISH_VALUE RedfishValue; + + if (IS_EMPTY_STRING (Schema) || IS_EMPTY_STRING (Version) || IS_EMPTY_ST= RING (ConfigureLang) || FeatureValue =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + + // + // Get the current value from HII + // + Status =3D 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 !=3D REDFISH_VALUE_TYPE_STRING) { + DEBUG ((DEBUG_ERROR, "%a, %a.%a %s value is not string type\n", __F= UNCTION__, Schema, Version, ConfigureLang)); + return EFI_DEVICE_ERROR; + } + + if (AsciiStrCmp (FeatureValue, RedfishValue.Value.Buffer) !=3D 0) { + // + // Apply settings from redfish + // + DEBUG ((DEBUG_INFO, "%a, %a.%a apply %s from %a to %a\n", __FUNCTION= __, Schema, Version, ConfigureLang, RedfishValue.Value.Buffer, FeatureValue= )); + + FreePool (RedfishValue.Value.Buffer); + RedfishValue.Value.Buffer =3D FeatureValue; + + Status =3D RedfishPlatformConfigSetValue (Schema, Version, Configure= Lang, RedfishValue); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a, apply %s to %s failed: %r\n", __FUNCTION= __, ConfigureLang, FeatureValue, Status)); + } + } else { + DEBUG ((DEBUG_ERROR, "%a, %a.%a %s value is: %s\n", __FUNCTION__, Sc= hema, Version, ConfigureLang, RedfishValue.Value.Buffer, Status)); + } + } + + return Status; +} + +/** + + Apply property value to UEFI HII database in numric type. + + @param[in] Schema Property schema. + @param[in] Version Property schema version. + @param[in] ConfigureLang Configure language refers to this property. + @param[in] FeatureValue New value to set. + + @retval EFI_SUCCESS New value is applied successfully. + @retval Others Errors occur. + +**/ +EFI_STATUS +ApplyFeatureSettingsNumericType ( + IN CHAR8 *Schema, + IN CHAR8 *Version, + IN EFI_STRING ConfigureLang, + IN INTN FeatureValue + ) +{ + EFI_STATUS Status; + EDKII_REDFISH_VALUE RedfishValue; + + if (IS_EMPTY_STRING (Schema) || IS_EMPTY_STRING (Version) || IS_EMPTY_ST= RING (ConfigureLang)) { + return EFI_INVALID_PARAMETER; + } + + // + // Get the current value from HII + // + Status =3D 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 !=3D REDFISH_VALUE_TYPE_INTEGER) { + DEBUG ((DEBUG_ERROR, "%a, %a.%a %s value is not numeric type\n", __= FUNCTION__, Schema, Version, ConfigureLang)); + return EFI_DEVICE_ERROR; + } + + if (RedfishValue.Value.Integer !=3D FeatureValue) { + // + // Apply settings from redfish + // + DEBUG ((DEBUG_INFO, "%a, %a.%a apply %s from 0x%x to 0x%x\n", __FUNC= TION__, Schema, Version, ConfigureLang, RedfishValue.Value.Integer, Feature= Value)); + + RedfishValue.Value.Integer =3D (INT64)FeatureValue; + + Status =3D RedfishPlatformConfigSetValue (Schema, Version, Configure= Lang, RedfishValue); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a, apply %s to 0x%x failed: %r\n", __FUNCTI= ON__, ConfigureLang, FeatureValue, Status)); + } + } else { + DEBUG ((DEBUG_ERROR, "%a, %a.%a %s value is: 0x%x\n", __FUNCTION__, = Schema, Version, ConfigureLang, RedfishValue.Value.Integer, Status)); + } + } + + return Status; +} + +/** + + Apply property value to UEFI HII database in boolean type. + + @param[in] Schema Property schema. + @param[in] Version Property schema version. + @param[in] ConfigureLang Configure language refers to this property. + @param[in] FeatureValue New value to set. + + @retval EFI_SUCCESS New value is applied successfully. + @retval Others Errors occur. + +**/ +EFI_STATUS +ApplyFeatureSettingsBooleanType ( + IN CHAR8 *Schema, + IN CHAR8 *Version, + IN EFI_STRING ConfigureLang, + IN BOOLEAN FeatureValue + ) +{ + EFI_STATUS Status; + EDKII_REDFISH_VALUE RedfishValue; + + if (IS_EMPTY_STRING (Schema) || IS_EMPTY_STRING (Version) || IS_EMPTY_ST= RING (ConfigureLang)) { + return EFI_INVALID_PARAMETER; + } + + // + // Get the current value from HII + // + Status =3D 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 !=3D REDFISH_VALUE_TYPE_BOOLEAN) { + DEBUG ((DEBUG_ERROR, "%a, %a.%a %s value is not boolean type\n", __= FUNCTION__, Schema, Version, ConfigureLang)); + return EFI_DEVICE_ERROR; + } + + if (RedfishValue.Value.Boolean !=3D FeatureValue) { + // + // Apply settings from redfish + // + DEBUG ((DEBUG_INFO, "%a, %a.%a apply %s from %a to %a\n", __FUNCTION= __, Schema, Version, ConfigureLang, (RedfishValue.Value.Boolean ? "True" : = "False"), (FeatureValue ? "True" : "False"))); + + RedfishValue.Value.Boolean =3D FeatureValue; + + Status =3D RedfishPlatformConfigSetValue (Schema, Version, Configure= Lang, RedfishValue); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a, apply %s to %a failed: %r\n", __FUNCTION= __, ConfigureLang, (FeatureValue ? "True" : "False"), Status)); + } + } else { + DEBUG ((DEBUG_ERROR, "%a, %a.%a %s value is: %a\n", __FUNCTION__, Sc= hema, Version, ConfigureLang, (RedfishValue.Value.Boolean ? "True" : "False= "), Status)); + } + } + + return Status; +} + +/** + + Read redfish resource by given resource path. + + @param[in] Service Redfish srvice instacne to make query. + @param[in] ResourcePath Target resource path. + @param[out] Response HTTP response from redfish service. + + @retval EFI_SUCCESS Resrouce is returned successfully. + @retval Others Errors occur. + +**/ +EFI_STATUS +GetResourceByPath ( + IN REDFISH_SERVICE *Service, + IN CHAR8 *ResourcePath, + OUT REDFISH_RESPONSE *Response + ) +{ + EFI_STATUS Status; + + if (Service =3D=3D NULL || Response =3D=3D NULL || IS_EMPTY_STRING (Reso= urcePath)) { + return EFI_INVALID_PARAMETER; + } + + // + // Get resource from redfish service. + // + Status =3D RedfishGetByService ( + Service, + ResourcePath, + Response + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a, RedfishGetByService to %a failed: %r\n", __F= UNCTION__, ResourcePath, Status)); + if (Response->Payload !=3D NULL) { + RedfishDumpPayload (Response->Payload); + RedfishFreeResponse ( + NULL, + 0, + NULL, + Response->Payload + ); + Response->Payload =3D NULL; + } + + return Status; + } + + return EFI_SUCCESS; +} + +/** + + Find array index from given configure language string. + + @param[in] ConfigureLang Configure language string to parse. + @param[out] UnifiedConfigureLang The configure language in array. + @param[out] Index The array index number. + + @retval EFI_SUCCESS Index is found. + @retval Others Errors occur. + +**/ +EFI_STATUS +GetArrayIndexFromArrayTypeConfigureLang ( + IN CHAR16 *ConfigureLang, + OUT CHAR16 **UnifiedConfigureLang, + OUT UINTN *Index + ) +{ + CHAR16 *TmpConfigureLang; + CHAR16 *IndexString; + CHAR16 *TmpString; + + if (ConfigureLang =3D=3D NULL || UnifiedConfigureLang =3D=3D NULL || Ind= ex =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + + TmpConfigureLang =3D AllocateCopyPool (StrSize (ConfigureLang), Configur= eLang); + if (TmpConfigureLang =3D=3D NULL) { + return EFI_OUT_OF_RESOURCES; + } + + // + // looking for index signature "{"" + // + IndexString =3D StrStr (TmpConfigureLang, BIOS_CONFIG_TO_REDFISH_REDPATH= _ARRAY_START_SIGNATURE); + if (IndexString =3D=3D NULL) { + return EFI_NOT_FOUND; + } + + // + // Skip "{" + // + TmpString =3D IndexString + StrLen (BIOS_CONFIG_TO_REDFISH_REDPATH_ARRAY= _START_SIGNATURE); + + // + // Looking for "}" + // + TmpString =3D StrStr (TmpString, BIOS_CONFIG_TO_REDFISH_REDPATH_ARRAY_EN= D_SIGNATURE); + if (TmpString =3D=3D NULL) { + return EFI_NOT_FOUND; + } + + // + // Append '\0' for converting decimal string to integer. + // + TmpString[0] =3D '\0'; + + // + // Convert decimal string to integer + // + *Index =3D StrDecimalToUintn (IndexString + StrLen (BIOS_CONFIG_TO_REDFI= SH_REDPATH_ARRAY_START_SIGNATURE)); + + // + // Resotre the '}' character and remove rest of string. + // + TmpString[0] =3D L'}'; + TmpString[1] =3D '\0'; + + *UnifiedConfigureLang =3D TmpConfigureLang; + + return EFI_SUCCESS; +} + +/** + + Search HII database with given Configure Language pattern. Data is handl= ed and + returned in array. + + @param[in] Schema The schema to search. + @param[in] Version The schema version. + @param[in] Pattern Configure Language pattern to sear= ch. + @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 *UnifiedConfigureLan= gList + ) +{ + 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_CON= FIG_TO_REDFISH_REDPATH_POOL_SIZE]; + + if (IS_EMPTY_STRING (Schema) || IS_EMPTY_STRING (Version) || UnifiedConf= igureLangList =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + + UnifiedConfigureLangList->Count =3D 0; + UnifiedConfigureLangList->List =3D NULL; + ZeroMem (UnifiedConfigureLangPool, sizeof (UnifiedConfigureLangPool)); + + Status =3D RedfishPlatformConfigGetConfigureLang (Schema, Version, Patte= rn, &ConfigureLangList, &Count); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a, RedfishFeatureGetConfigureLangRegex failed: = %r\n", __FUNCTION__, Status)); + return Status; + } + + if (Count =3D=3D 0) { + return EFI_NOT_FOUND; + } + + for (Index =3D 0; Index < Count; Index++) { + Status =3D GetArrayIndexFromArrayTypeConfigureLang (ConfigureLangList[= Index], &UnifiedConfigureLang, &ArrayIndex); + if (EFI_ERROR (Status)) { + ASSERT (FALSE); + continue; + } + + // + // Check if this configure language is duplicated. + // + Duplicated =3D FALSE; + for (Index2 =3D 0; Index2 < BIOS_CONFIG_TO_REDFISH_REDPATH_POOL_SIZE; = Index2++) { + if (UnifiedConfigureLangPool[Index2].ConfigureLang =3D=3D NULL) { + break; + } + + if (StrCmp (UnifiedConfigureLangPool[Index2].ConfigureLang, UnifiedC= onfigureLang) =3D=3D 0) { + Duplicated =3D TRUE; + break; + } + } + + if (Duplicated) { + FreePool (UnifiedConfigureLang); + continue; + } + + if (UnifiedConfigureLangList->Count >=3D BIOS_CONFIG_TO_REDFISH_REDPAT= H_POOL_SIZE) { + FreePool (UnifiedConfigureLang); + Status =3D EFI_BUFFER_TOO_SMALL; + break; + } + + // + // New configure language. Keep it in Pool + // + + UnifiedConfigureLangPool[UnifiedConfigureLangList->Count].ConfigureLan= g =3D UnifiedConfigureLang; + UnifiedConfigureLangPool[UnifiedConfigureLangList->Count].Index =3D Ar= rayIndex; + ++UnifiedConfigureLangList->Count; + } + + FreePool (ConfigureLangList); + + // + // Prepare the result to caller. + // + UnifiedConfigureLangList->List =3D AllocateCopyPool (sizeof (REDFISH_FEA= TURE_ARRAY_TYPE_CONFIG_LANG) * UnifiedConfigureLangList->Count, UnifiedConf= igureLangPool); + + return Status; +} + +/** + + Create HTTP payload and send them to redfish service with PATCH method. + + @param[in] Service Redfish service. + @param[in] TargetPayload Target payload + @param[in] Json Data in JSON format. + @param[out] Etag Returned ETAG string from Redfish service. + + @retval EFI_SUCCESS Data is sent to redfish service successfully. + @retval Others Errors occur. + +**/ +EFI_STATUS +CreatePayloadToPatchResource ( + IN REDFISH_SERVICE *Service, + IN REDFISH_PAYLOAD *TargetPayload, + IN CHAR8 *Json, + OUT CHAR8 **Etag + ) +{ + REDFISH_PAYLOAD Payload; + EDKII_JSON_VALUE ResourceJsonValue; + REDFISH_RESPONSE PostResponse; + EFI_STATUS Status; + UINTN Index; + EDKII_JSON_VALUE JsonValue; + EDKII_JSON_VALUE OdataIdValue; + CHAR8 *OdataIdString; + + if (Service =3D=3D NULL || TargetPayload =3D=3D NULL || IS_EMPTY_STRING = (Json) || Etag =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + + ResourceJsonValue =3D JsonLoadString (Json, 0, NULL); + Payload =3D RedfishCreatePayload (ResourceJsonValue, Service); + if (Payload =3D=3D NULL) { + DEBUG ((DEBUG_ERROR, "%a:%d Failed to create JSON payload from JSON va= lue!\n",__FUNCTION__, __LINE__)); + Status =3D EFI_DEVICE_ERROR; + goto EXIT_FREE_JSON_VALUE; + } + + ZeroMem (&PostResponse, sizeof (REDFISH_RESPONSE)); + Status =3D RedfishPatchToPayload (TargetPayload, Payload, &PostResponse); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a:%d Failed to PATCH payload to Redfish service= .\n",__FUNCTION__, __LINE__)); + goto EXIT_FREE_JSON_VALUE; + } + + + // + // Keep etag. + // + *Etag =3D NULL; + if (*PostResponse.StatusCode =3D=3D HTTP_STATUS_200_OK) { + if (PostResponse.HeaderCount !=3D 0) { + for (Index =3D 0; Index < PostResponse.HeaderCount; Index++) { + if (AsciiStrnCmp (PostResponse.Headers[Index].FieldName, "ETag", 4= ) =3D=3D 0) { + *Etag =3D AllocateCopyPool (AsciiStrSize (PostResponse.Headers[I= ndex].FieldValue), PostResponse.Headers[Index].FieldValue); + } + } + } else if (PostResponse.Payload !=3D NULL) { + // + // No header is returned. Search payload for location. + // + JsonValue =3D RedfishJsonInPayload (PostResponse.Payload); + if (JsonValue !=3D NULL) { + OdataIdValue =3D JsonObjectGetValue (JsonValueGetObject (JsonValue= ), "@odata.etag"); + if (OdataIdValue !=3D NULL) { + OdataIdString =3D (CHAR8 *)JsonValueGetAsciiString (OdataIdValue= ); + if (OdataIdString !=3D NULL) { + *Etag =3D AllocateCopyPool (AsciiStrSize (OdataIdString), Odat= aIdString); + } + } + } + } + } + + RedfishFreeResponse ( + PostResponse.StatusCode, + PostResponse.HeaderCount, + PostResponse.Headers, + PostResponse.Payload + ); + +EXIT_FREE_JSON_VALUE: + if (Payload !=3D 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 servic= e. + @param[out] Etag Returned ETAG string from Redfish service. + + @retval EFI_SUCCESS Data is sent to redfish service successfully. + @retval Others Errors occur. + +**/ +EFI_STATUS +CreatePayloadToPostResource ( + IN REDFISH_SERVICE *Service, + IN REDFISH_PAYLOAD *TargetPayload, + IN CHAR8 *Json, + OUT CHAR8 **Location, + OUT CHAR8 **Etag + ) +{ + REDFISH_PAYLOAD Payload; + EDKII_JSON_VALUE ResourceJsonValue; + REDFISH_RESPONSE PostResponse; + EFI_STATUS Status; + UINTN Index; + EDKII_JSON_VALUE JsonValue; + EDKII_JSON_VALUE OdataIdValue; + CHAR8 *OdataIdString; + + if (Service =3D=3D NULL || TargetPayload =3D=3D NULL || IS_EMPTY_STRING = (Json) || Location =3D=3D NULL || Etag =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + + ResourceJsonValue =3D JsonLoadString (Json, 0, NULL); + Payload =3D RedfishCreatePayload (ResourceJsonValue, Service); + if (Payload =3D=3D NULL) { + DEBUG ((DEBUG_ERROR, "%a:%d Failed to create JSON payload from JSON va= lue!\n",__FUNCTION__, __LINE__)); + Status =3D EFI_DEVICE_ERROR; + goto EXIT_FREE_JSON_VALUE; + } + + ZeroMem (&PostResponse, sizeof (REDFISH_RESPONSE)); + Status =3D RedfishPostToPayload (TargetPayload, Payload, &PostResponse); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a:%d Failed to POST Attribute Registry to Redfi= sh service.\n",__FUNCTION__, __LINE__)); + goto EXIT_FREE_JSON_VALUE; + } + + // + // per Redfish spec. the URL of new eresource will be returned in "Locat= ion" header. + // + *Location =3D NULL; + *Etag =3D NULL; + if (*PostResponse.StatusCode =3D=3D HTTP_STATUS_200_OK) { + if (PostResponse.HeaderCount !=3D 0) { + for (Index =3D 0; Index < PostResponse.HeaderCount; Index++) { + if (AsciiStrnCmp (PostResponse.Headers[Index].FieldName, "Location= ", 8) =3D=3D 0) { + *Location =3D AllocateCopyPool (AsciiStrSize (PostResponse.Heade= rs[Index].FieldValue), PostResponse.Headers[Index].FieldValue); + } else if (AsciiStrnCmp (PostResponse.Headers[Index].FieldName, "E= Tag", 4) =3D=3D 0) { + *Etag =3D AllocateCopyPool (AsciiStrSize (PostResponse.Headers[I= ndex].FieldValue), PostResponse.Headers[Index].FieldValue); + } + } + } else if (PostResponse.Payload !=3D NULL) { + // + // No header is returned. Search payload for location. + // + JsonValue =3D RedfishJsonInPayload (PostResponse.Payload); + if (JsonValue !=3D NULL) { + OdataIdValue =3D JsonObjectGetValue (JsonValueGetObject (JsonValue= ), "@odata.id"); + if (OdataIdValue !=3D NULL) { + OdataIdString =3D (CHAR8 *)JsonValueGetAsciiString (OdataIdValue= ); + if (OdataIdString !=3D NULL) { + *Location =3D AllocateCopyPool (AsciiStrSize (OdataIdString), = OdataIdString); + } + } + + OdataIdValue =3D JsonObjectGetValue (JsonValueGetObject (JsonValue= ), "@odata.etag"); + if (OdataIdValue !=3D NULL) { + OdataIdString =3D (CHAR8 *)JsonValueGetAsciiString (OdataIdValue= ); + if (OdataIdString !=3D NULL) { + *Etag =3D AllocateCopyPool (AsciiStrSize (OdataIdString), Odat= aIdString); + } + } + } + } + } + + // + // This is not expected as service does not follow spec. + // + if (*Location =3D=3D NULL) { + Status =3D EFI_DEVICE_ERROR; + } + + RedfishFreeResponse ( + PostResponse.StatusCode, + PostResponse.HeaderCount, + PostResponse.Headers, + PostResponse.Payload + ); + + RedfishCleanupPayload (Payload); + +EXIT_FREE_JSON_VALUE: + JsonValueFree (JsonValue); + JsonValueFree (ResourceJsonValue); + + return Status; +} + +/** + + Find Redfish Resource Config Protocol that supports given schema and ver= sion. + + @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 proto= col + @retval NULL No protocol foun= d. + +**/ +EDKII_REDFISH_RESOURCE_CONFIG_PROTOCOL * +GetRedfishResourceConfigProtocol ( + IN CHAR8 *Schema, + IN CHAR8 *Major, + IN CHAR8 *Minor, + IN CHAR8 *Errata + ) +{ + EFI_STATUS Status; + EFI_HANDLE *HandleBuffer; + UINTN NumberOfHandles; + UINTN Index; + EDKII_REDFISH_RESOURCE_CONFIG_PROTOCOL *Protocol; + REDFISH_SCHEMA_INFO SchemaInfo; + BOOLEAN Found; + + if (IS_EMPTY_STRING (Schema) || IS_EMPTY_STRING (Major) || IS_EMPTY_STRI= NG (Minor) || IS_EMPTY_STRING (Errata)) { + return NULL; + } + + Status =3D gBS->LocateHandleBuffer ( + ByProtocol, + &gEdkIIRedfishResourceConfigProtocolGuid, + NULL, + &NumberOfHandles, + &HandleBuffer + ); + if (EFI_ERROR (Status)) { + return NULL; + } + + Found =3D FALSE; + + for (Index =3D 0; Index < NumberOfHandles; Index++) { + Status =3D gBS->HandleProtocol ( + HandleBuffer[Index], + &gEdkIIRedfishResourceConfigProtocolGuid, + (VOID **) &Protocol + ); + if (EFI_ERROR (Status)) { + continue; + } + + Status =3D Protocol->GetInfo (Protocol, &SchemaInfo); + if (EFI_ERROR (Status)) { + continue; + } + + if (AsciiStrCmp (Schema, SchemaInfo.Schema) =3D=3D 0 && + AsciiStrCmp (Major, SchemaInfo.Major) =3D=3D 0 && + AsciiStrCmp (Minor, SchemaInfo.Minor) =3D=3D 0 && + AsciiStrCmp (Errata, SchemaInfo.Errata) =3D=3D 0) { + Found =3D TRUE; + break; + } + } + + FreePool (HandleBuffer); + + return (Found ? Protocol : NULL); +} + +/** + + Get supported schema list by given specify schema name. + + @param[in] Schema Schema type name. + @param[out] SchemaInfo Returned schema information. + + @retval EFI_SUCCESS Schema information is returned successfu= lly. + @retval Others Errors occur. + +**/ +EFI_STATUS +GetSupportedSchemaVersion ( + IN CHAR8 *Schema, + OUT REDFISH_SCHEMA_INFO *SchemaInfo + ) +{ + EFI_STATUS Status; + CHAR8 *SupportSchema; + CHAR8 *SchemaName; + UINTN Index; + UINTN Index2; + BOOLEAN Found; + + if (IS_EMPTY_STRING (Schema) || SchemaInfo =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + + Status =3D RedfishPlatformConfigGetSupportedSchema (NULL, &SupportSchema= ); + if (EFI_ERROR (Status)) { + return Status; + } + + DEBUG ((DEBUG_INFO, "Supported schema: %a\n", SupportSchema)); + + Index =3D 0; + Found =3D FALSE; + SchemaName =3D SupportSchema; + while (TRUE) { + + if (SupportSchema[Index] =3D=3D ';' || SupportSchema[Index] =3D=3D '\0= ') { + if (AsciiStrnCmp (&SchemaName[SCHEMA_NAME_PREFIX_OFFSET], Schema, As= ciiStrLen (Schema)) =3D=3D 0) { + Found =3D TRUE; + SupportSchema[Index] =3D '\0'; + break; + } + + SchemaName =3D &SupportSchema[Index + 1]; + } + + if (SupportSchema[Index] =3D=3D '\0') { + break; + } + + ++Index; + } + + if (Found) { + + AsciiStrCpyS (SchemaInfo->Schema, REDFISH_SCHEMA_STRING_SIZE, Schema); + + // + // forward to '.' + // + Index =3D 0; + while (SchemaName[Index] !=3D '\0' && SchemaName[Index] !=3D '.') { + ++Index; + } + ASSERT (SchemaName[Index] !=3D '\0'); + + // + // Skip '.' and 'v' + // + Index +=3D 2; + + // + // forward to '_' + // + Index2 =3D Index; + while (SchemaName[Index2] !=3D '\0' && SchemaName[Index2] !=3D '_') { + ++Index2; + } + ASSERT (SchemaName[Index2] !=3D '\0'); + + AsciiStrnCpyS (SchemaInfo->Major, REDFISH_SCHEMA_VERSION_SIZE, &Schema= Name[Index], (Index2 - Index)); + Index =3D Index2; + + // + // Skip '_' + // + ++Index; + + // + // forward to '_' + // + Index2 =3D Index; + while (SchemaName[Index2] !=3D '\0' && SchemaName[Index2] !=3D '_') { + ++Index2; + } + ASSERT (SchemaName[Index2] !=3D '\0'); + + AsciiStrnCpyS (SchemaInfo->Minor, REDFISH_SCHEMA_VERSION_SIZE, &Schema= Name[Index], (Index2 - Index)); + Index =3D Index2; + + // + // Skip '_' + // + ++Index; + + AsciiStrCpyS (SchemaInfo->Errata, REDFISH_SCHEMA_VERSION_SIZE, &Schema= Name[Index]); + } + + FreePool (SupportSchema); + + return (Found ? EFI_SUCCESS : EFI_NOT_FOUND); +} + +/** + + Return system root path. This is dummy function now. + + @retval NULL Can not find system root path. + @retval Other System root path is returned. + +**/ +CHAR8 * +RedfishGetSystemRootPath ( + VOID + ) +{ + return AllocateCopyPool (AsciiStrSize (REDFISH_SYSTEM_ROOT_PATH), REDFIS= H_SYSTEM_ROOT_PATH); +} + +/** + + Get schema information by given protocol and service instance. + + @param[in] RedfishService Pointer to Redfish service instance. + @param[in] JsonStructProtocol Json Structure protocol instance. + @param[in] Uri Target URI. + @param[out] SchemaInfo Returned schema information. + + @retval EFI_SUCCESS Schema information is returned successfu= lly. + @retval Others Errors occur. + +**/ +EFI_STATUS +GetRedfishSchemaInfo ( + IN REDFISH_SERVICE *RedfishService, + IN EFI_REST_JSON_STRUCTURE_PROTOCOL *JsonStructProtocol, + IN CHAR8 *Uri, + OUT REDFISH_SCHEMA_INFO *SchemaInfo + ) +{ + EFI_STATUS Status; + REDFISH_RESPONSE Response; + REDFISH_PAYLOAD Payload; + CHAR8 *JsonText; + EFI_REST_JSON_STRUCTURE_HEADER *Header; + + if (RedfishService =3D=3D NULL || JsonStructProtocol =3D=3D NULL || IS_E= MPTY_STRING (Uri) || SchemaInfo =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + + Status =3D GetResourceByPath (RedfishService, Uri, &Response); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a, failed to get resource from %a %r", __FUNCTI= ON__, Uri, Status)); + return Status; + } + + Payload =3D Response.Payload; + ASSERT (Payload !=3D NULL); + + JsonText =3D JsonDumpString (RedfishJsonInPayload (Payload), EDKII_JSON_= COMPACT); + ASSERT (JsonText !=3D NULL); + + // + // Convert JSON text to C structure. + // + Status =3D JsonStructProtocol->ToStructure ( + JsonStructProtocol, + NULL, + JsonText, + &Header + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a, ToStructure() failed: %r\n", __FUNCTION__, S= tatus)); + return Status; + } + + AsciiStrCpyS (SchemaInfo->Schema, REDFISH_SCHEMA_STRING_SIZE, Header->J= sonRsrcIdentifier.NameSpace.ResourceTypeName); + AsciiStrCpyS (SchemaInfo->Major, REDFISH_SCHEMA_VERSION_SIZE, Header->J= sonRsrcIdentifier.NameSpace.MajorVersion); + AsciiStrCpyS (SchemaInfo->Minor, REDFISH_SCHEMA_VERSION_SIZE, Header->J= sonRsrcIdentifier.NameSpace.MinorVersion); + AsciiStrCpyS (SchemaInfo->Errata, REDFISH_SCHEMA_VERSION_SIZE, Header->= JsonRsrcIdentifier.NameSpace.ErrataVersion); + + // + // Release resource. + // + JsonStructProtocol->DestoryStructure (JsonStructProtocol, Header); + FreePool (JsonText); + RedfishFreeResponse (Response.StatusCode, Response.HeaderCount, Response= .Headers, Response.Payload); + + return EFI_SUCCESS; +} + +/** + + Get the property name by given Configure Langauge. + + @param[in] ConfigureLang Configure Language string. + + @retval EFI_STRING Pointer to property name. + @retval NULL There is error. + +**/ +EFI_STRING +GetPropertyFromConfigureLang ( + IN EFI_STRING ConfigureLang + ) +{ + EFI_STRING Property; + UINTN Index; + + if (ConfigureLang =3D=3D NULL) { + return NULL; + } + + Index =3D 0; + Property =3D ConfigureLang; + + while (ConfigureLang[Index] !=3D '\0') { + if (ConfigureLang[Index] =3D=3D L'/') { + Property =3D &ConfigureLang[Index]; + } + + ++Index; + } + + ++Property; + + return Property; +} + +/** + + Get the property value in string type. + + @param[in] Schema Schema of this property. + @param[in] Version Schema version. + @param[in] PropertyName Property name. + @param[in] ConfigureLang Configure Language of this property. + + @retval CHAR8* Pointer to the CHAR8 buffer. + @retval NULL There is error. + +**/ +CHAR8 * +GetPropertyStringValue ( + IN CHAR8 *Schema, + IN CHAR8 *Version, + IN EFI_STRING PropertyName, + IN EFI_STRING ConfigureLang + ) +{ + EFI_STATUS Status; + EDKII_REDFISH_VALUE RedfishValue; + EFI_STRING ConfigureLangBuffer; + UINTN BufferSize; + CHAR8 *AsciiStringValue; + + if (IS_EMPTY_STRING (Schema) || IS_EMPTY_STRING (Version) || IS_EMPTY_ST= RING (ConfigureLang) || IS_EMPTY_STRING (PropertyName)) { + return NULL; + } + + // + // Configure Language buffer. + // + BufferSize =3D sizeof (CHAR16) * MAX_CONF_LANG_LEN; + ConfigureLangBuffer =3D AllocatePool (BufferSize); + if (ConfigureLangBuffer =3D=3D NULL) { + return NULL; + } + + UnicodeSPrint (ConfigureLangBuffer, BufferSize, L"%s/%s", ConfigureLang,= PropertyName); + Status =3D RedfishPlatformConfigGetValue (Schema, Version, ConfigureLang= Buffer, &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 !=3D REDFISH_VALUE_TYPE_STRING) { + DEBUG ((DEBUG_ERROR, "%a, %a.%a %s value is not string type\n", __FUNC= TION__, Schema, Version, ConfigureLang)); + return NULL; + } + + AsciiStringValue =3D AllocateCopyPool (AsciiStrSize (RedfishValue.Value.= Buffer), RedfishValue.Value.Buffer); + ASSERT (AsciiStringValue !=3D 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_ST= RING (ConfigureLang) || IS_EMPTY_STRING (PropertyName)) { + return NULL; + } + + // + // Configure Language buffer. + // + BufferSize =3D sizeof (CHAR16) * MAX_CONF_LANG_LEN; + ConfigureLangBuffer =3D AllocatePool (BufferSize); + if (ConfigureLangBuffer =3D=3D NULL) { + return NULL; + } + + UnicodeSPrint (ConfigureLangBuffer, BufferSize, L"%s/%s", ConfigureLang,= PropertyName); + Status =3D RedfishPlatformConfigGetValue (Schema, Version, ConfigureLang= Buffer, &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 !=3D REDFISH_VALUE_TYPE_INTEGER) { + DEBUG ((DEBUG_ERROR, "%a, %a.%a %s value is not numeric type\n", __FUN= CTION__, Schema, Version, ConfigureLang)); + return NULL; + } + + ResultValue =3D AllocatePool (sizeof (INT64)); + ASSERT (ResultValue !=3D NULL); + if (ResultValue =3D=3D NULL) { + return NULL; + } + + *ResultValue =3D 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_ST= RING (ConfigureLang) || IS_EMPTY_STRING (PropertyName)) { + return NULL; + } + + // + // Configure Language buffer. + // + BufferSize =3D sizeof (CHAR16) * MAX_CONF_LANG_LEN; + ConfigureLangBuffer =3D AllocatePool (BufferSize); + if (ConfigureLangBuffer =3D=3D NULL) { + return NULL; + } + + UnicodeSPrint (ConfigureLangBuffer, BufferSize, L"%s/%s", ConfigureLang,= PropertyName); + Status =3D RedfishPlatformConfigGetValue (Schema, Version, ConfigureLang= Buffer, &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 !=3D REDFISH_VALUE_TYPE_BOOLEAN) { + DEBUG ((DEBUG_ERROR, "%a, %a.%a %s value is not boolean type\n", __FUN= CTION__, Schema, Version, ConfigureLang)); + return NULL; + } + + ResultValue =3D AllocatePool (sizeof (BOOLEAN)); + ASSERT (ResultValue !=3D NULL); + if (ResultValue =3D=3D NULL) { + return NULL; + } + + *ResultValue =3D RedfishValue.Value.Boolean; + + return ResultValue; +} + +/** + + Check and see if we need to do provisioning for this property. + + @param[in] PropertyBuffer Pointer to property instance. + @param[in] ProvisionMode TRUE if we are in provision mode. FALSE oth= erwise. + + @retval TRUE Provision is required. + @retval FALSE Provision is not required. + +**/ +BOOLEAN +PropertyChecker ( + IN VOID *PropertyBuffer, + IN BOOLEAN ProvisionMode + ) +{ + if (ProvisionMode && PropertyBuffer =3D=3D NULL) { + return TRUE; + } + + if (!ProvisionMode && PropertyBuffer !=3D NULL) { + return TRUE; + } + + return FALSE; +} + +/** + + Check and see if we need to do provisioning for this two properties. + + @param[in] PropertyBuffer1 Pointer to property instance 1. + @param[in] PropertyBuffer2 Pointer to property instance 2. + @param[in] ProvisionMode TRUE if we are in provision mode. FALSE ot= herwise. + + @retval TRUE Provision is required. + @retval FALSE Provision is not required. + +**/ +BOOLEAN +PropertyChecker2Parm ( + IN VOID *PropertyBuffer1, + IN VOID *PropertyBuffer2, + IN BOOLEAN ProvisionMode + ) +{ + if (ProvisionMode && (PropertyBuffer1 =3D=3D NULL || PropertyBuffer2 =3D= =3D NULL)) { + return TRUE; + } + + if (!ProvisionMode && PropertyBuffer1 !=3D NULL && PropertyBuffer2 !=3D = NULL) { + return TRUE; + } + + return FALSE; +} + +/** + + Install Boot Maintenance Manager Menu driver. + + @param[in] ImageHandle The image handle. + @param[in] SystemTable The system table. + + @retval EFI_SUCEESS Install Boot manager menu success. + @retval Other Return error status. + +**/ +EFI_STATUS +EFIAPI +RedfishFeatureUtilityLibConstructor ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + + return EFI_SUCCESS; +} + +/** + Unloads the application and its installed protocol. + + @param[in] ImageHandle Handle that identifies the image to be unlo= aded. + @param[in] SystemTable The system table. + + @retval EFI_SUCCESS The image has been unloaded. + +**/ +EFI_STATUS +EFIAPI +RedfishFeatureUtilityLibDestructor ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + return EFI_SUCCESS; +} --=20 2.21.0.windows.1 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#82779): https://edk2.groups.io/g/devel/message/82779 Mute This Topic: https://groups.io/mt/86643507/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-