From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from NAM12-BN8-obe.outbound.protection.outlook.com (NAM12-BN8-obe.outbound.protection.outlook.com [40.107.237.84]) by mx.groups.io with SMTP id smtpd.web10.51651.1683210361981891542 for ; Thu, 04 May 2023 07:26:02 -0700 Authentication-Results: mx.groups.io; dkim=fail reason="body hash did not verify" header.i=@nvidia.com header.s=selector2 header.b=elcR0wz1; spf=permerror, err=parse error for token &{10 18 %{i}._ip.%{h}._ehlo.%{d}._spf.vali.email}: invalid domain name (domain: nvidia.com, ip: 40.107.237.84, mailfrom: nicklew@nvidia.com) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=EcQTgnd0YE8mgRCg9PyFEhDRez87JDGfqMQm1jjqPfepzXmRDF/zNYuspqf59aTnB2Lcxosi1nf2gXi3G/GQg0kh1PB6Kk3S8f6mS7soS9zgcghCTxYzdvOtSs2MTht3POJv779T5uQ0Tb/sKNRALaD+vS1/Agn+XXStO3DTAGuqhWwkapk31SBedvHigJSNX+9dda/iKQDEjtTS4cPjUdMS123UPOJ30Jwn9V5frunTJR097bvjc3liGs6vEHoteXeiPEn014D6HFdIWPkNuoXXQFlvqHI3CNJtb1KmYUzm1I6R1f71K+rLzxSaXk3GEkOPAYcml6nDRq/HaM0O8Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=8aX4ScevdDESQI6mz5y0AcKVC9GtHJRLtmqKME37lhQ=; b=OjsWe7OTwIQIRrsvQEdEk5BcZVw/Bbt7LZMjj4ilw8Gtw4/gw39CxqVv0N1Mc5J/VSd3ehMlSpU6BqIuHJOqXQwEznzye9npWFPkZwm5P6ivuEELsMKNSVLvh88MskdqgLTE9BaP6eIHRw4lrm9FwH7cgN2YwuYmZfcNzVDdFLna7GwyCtHOMcCktF20bg6Pc62ynwHHFuCs5z6iK+UXbo8UZWdG9lZvQHff0+nrW36V/4QXWmX4VytAi5eOAcQ0qoo48HLi0nbfyFwFw3amrtEAvixYt9tKjSMZWP7VRx51rX6meyWKvQSdczIPIlp3a6BR3QOSFUR02i5jl+cINQ== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 216.228.118.232) smtp.rcpttodomain=edk2.groups.io smtp.mailfrom=nvidia.com; dmarc=pass (p=reject sp=reject pct=100) action=none header.from=nvidia.com; dkim=none (message not signed); arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=Nvidia.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=8aX4ScevdDESQI6mz5y0AcKVC9GtHJRLtmqKME37lhQ=; b=elcR0wz1RPRj6rTe4dp3kgCKEKyFTBa8nIP7zPLiupiB842faeVAtU6HeX9Znh8VqJC1ENL1CDI2/7FUt0r+XK+lRkgyYe8VpvW/b7iPpjAtW49fiwuWR/pH0+jFkPMX9PcfYrQOVSteSJYSpFScSSMU43irI805Wtng5N6+/z3LaZT9KlktU8R44CknzOq8GRLPfQYyS0w9NyCj7ZglO8Q9tXfJECjkot6T9KyKxc8IWfdkjNSPVnCkPxYMzovhOOlh26Bz860Ma3dakQPbGn+8Z9P6yMUCRbF58acik+xozph36q/n5EhJxuCfbbvO2qUUu8fx/pQ+2SFV3U4+6A== Received: from BN8PR04CA0049.namprd04.prod.outlook.com (2603:10b6:408:d4::23) by DS0PR12MB7629.namprd12.prod.outlook.com (2603:10b6:8:13e::13) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6363.26; Thu, 4 May 2023 14:25:57 +0000 Received: from BN8NAM11FT110.eop-nam11.prod.protection.outlook.com (2603:10b6:408:d4:cafe::35) by BN8PR04CA0049.outlook.office365.com (2603:10b6:408:d4::23) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6363.26 via Frontend Transport; Thu, 4 May 2023 14:25:57 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 216.228.118.232) smtp.mailfrom=nvidia.com; dkim=none (message not signed) header.d=none;dmarc=pass action=none header.from=nvidia.com; Received-SPF: Pass (protection.outlook.com: domain of nvidia.com designates 216.228.118.232 as permitted sender) receiver=protection.outlook.com; client-ip=216.228.118.232; helo=mail.nvidia.com; pr=C Received: from mail.nvidia.com (216.228.118.232) by BN8NAM11FT110.mail.protection.outlook.com (10.13.176.156) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6363.26 via Frontend Transport; Thu, 4 May 2023 14:25:57 +0000 Received: from drhqmail203.nvidia.com (10.126.190.182) by mail.nvidia.com (10.127.129.5) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.986.5; Thu, 4 May 2023 07:25:42 -0700 Received: from drhqmail202.nvidia.com (10.126.190.181) by drhqmail203.nvidia.com (10.126.190.182) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.986.37; Thu, 4 May 2023 07:25:41 -0700 Received: from NV-CL38DL3.nvidia.com (10.127.8.9) by mail.nvidia.com (10.126.190.181) with Microsoft SMTP Server id 15.2.986.37 via Frontend Transport; Thu, 4 May 2023 07:25:40 -0700 From: "Nickle Wang" To: CC: Abner Chang , Igor Kulchytskyy Subject: [edk2-redfish-client][PATCH 6/8] RedfishClientPkg: Add Redfish Feature Utility library Date: Thu, 4 May 2023 22:25:40 +0800 Message-ID: <20230504142540.17996-1-nicklew@nvidia.com> X-Mailer: git-send-email 2.17.1 MIME-Version: 1.0 Return-Path: nicklew@nvidia.com X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: BN8NAM11FT110:EE_|DS0PR12MB7629:EE_ X-MS-Office365-Filtering-Correlation-Id: c28758ce-ceda-411a-20b9-08db4cab7a27 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: 8LSaSz0ksGSk5IHBh/LOLof8kTQeP0m24jXvLCeD4G66FbzNrhv6UXvRk1XkcxS/LBdsrGB4REkF+oZW+jp8kfKbFeSpiWQ/uM1JYaGYmYYmXHNqZBBPE15nhTfJBu5rJtlaQk3fStg05g619zXq6zmXxIDkwHtNKCQxP+s/bLLRJBNs1FAumcsDGRVGsySXOZLYAHKe/DUw4tGNSJbRXDtkgFOo1B68KkQpK8ey1p149D/05hHiVyzFwNgaBh363QLHe5kk5Ixtih9OC21gwYyjR0+sIgj8N1e3yrbHRO1DPS+7bcu2nu5ejp4LPZp5L5aBCXSfelRetLs++ZwPERU7O8oWLXqVM51zyG0vJ2iseg1+FOILQazGk+L8k7SP+dJpQgIWXbUa2V8JyhBkbi33tg2lpQ0SbjCPo0VVN6TMWjJWiPJmJyL3DKJSMdVk0x2H9DplcoFTtsp/uyTwbJ3XtjKkS5wSB+7jSfj+TyLovkpFde0SQ7EYo2qHV22bDj8Qhf2UjZ513gMpoaVSQVc1ya8QVMXwnL3y6MjCDOZk/RLhTq/iI/lAkRbXbtYGBHLClT3T4nKJRtphMvsGduSHOBW5xnFHyoSVsxMn3eFWGlsGgt/R1q+K1inIiWEfn3sngT8uZftdMU/sOwUYvqN76RvCq4mJnDcnf1Vp7q2G8QUbZrU3yhbkpkIbDzfqUJ6uMnxm97xZQ4BsKF5XWw== X-Forefront-Antispam-Report: CIP:216.228.118.232;CTRY:US;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:mail.nvidia.com;PTR:dc7edge1.nvidia.com;CAT:NONE;SFS:(13230028)(4636009)(376002)(346002)(396003)(39860400002)(136003)(451199021)(46966006)(40470700004)(36840700001)(316002)(41300700001)(30864003)(2906002)(186003)(26005)(2616005)(82310400005)(7696005)(6916009)(336012)(4326008)(1076003)(426003)(86362001)(70206006)(47076005)(70586007)(36860700001)(36756003)(54906003)(478600001)(40460700003)(8936002)(82740400003)(8676002)(5660300002)(356005)(7636003)(40480700001)(579004)(559001);DIR:OUT;SFP:1101; X-OriginatorOrg: Nvidia.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 04 May 2023 14:25:57.3685 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: c28758ce-ceda-411a-20b9-08db4cab7a27 X-MS-Exchange-CrossTenant-Id: 43083d15-7273-40c1-b7db-39efd9ccc17a X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=43083d15-7273-40c1-b7db-39efd9ccc17a;Ip=[216.228.118.232];Helo=[mail.nvidia.com] X-MS-Exchange-CrossTenant-AuthSource: BN8NAM11FT110.eop-nam11.prod.protection.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: DS0PR12MB7629 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain This is the helper library for EDKII Redfish feature drivers to manipulate Redfish properties. Signed-off-by: Nickle Wang Cc: Abner Chang Cc: Igor Kulchytskyy --- RedfishClientPkg/RedfishClientPkg.dec | 3 + RedfishClientPkg/RedfishClientLibs.dsc.inc | 3 + RedfishClientPkg/RedfishClientPkg.dsc | 2 + .../RedfishFeatureUtilityLib.inf | 50 + .../Library/RedfishFeatureUtilityLib.h | 471 +++++ .../RedfishFeatureUtilityInternal.h | 45 + .../RedfishFeatureUtilityLib.c | 1513 +++++++++++++++++ 7 files changed, 2087 insertions(+) create mode 100644 RedfishClientPkg/Library/RedfishFeatureUtilityLib/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 f0fe3269..b965f915 100644 --- a/RedfishClientPkg/RedfishClientPkg.dec +++ b/RedfishClientPkg/RedfishClientPkg.dec @@ -19,6 +19,9 @@ PrivateInclude # Private header files PrivateInclude/Crt # Private header files for C RTL. =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 7e313ae5..a5ae73ca 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 adb50cec..00a963ea 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 00000000..f9f283fd --- /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 00000000..928fa4e8 --- /dev/null +++ b/RedfishClientPkg/Include/Library/RedfishFeatureUtilityLib.h @@ -0,0 +1,471 @@ +/** @file + This file defines the Redfish Feature Utility Library interface. + + (C) Copyright 2021 Hewlett Packard Enterprise Development LP
+ + 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 00000000..cfb9759a --- /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 00000000..605283b9 --- /dev/null +++ b/RedfishClientPkg/Library/RedfishFeatureUtilityLib/RedfishFeatureUtili= tyLib.c @@ -0,0 +1,1513 @@ +/** @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", __FU= NCTION__, 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", __F= UNCTION__, 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", __F= UNCTION__, 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 (= ResourcePath)) { + 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) ||= (Index =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_CO= NFIG_TO_REDFISH_REDPATH_POOL_SIZE]; + + if (IS_EMPTY_STRING (Schema) || IS_EMPTY_STRING (Version) || (UnifiedCon= figureLangList =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 ArrayIndex; + ++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_STR= ING (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_STR= ING (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_EMPTY_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->Js= onRsrcIdentifier.NameSpace.ResourceTypeName); + AsciiStrCpyS (SchemaInfo->Major, REDFISH_SCHEMA_VERSION_SIZE, Header->Js= onRsrcIdentifier.NameSpace.MajorVersion); + AsciiStrCpyS (SchemaInfo->Minor, REDFISH_SCHEMA_VERSION_SIZE, Header->Js= onRsrcIdentifier.NameSpace.MinorVersion); + AsciiStrCpyS (SchemaInfo->Errata, REDFISH_SCHEMA_VERSION_SIZE, Header->J= sonRsrcIdentifier.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.17.1