From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by spool.mail.gandi.net (Postfix) with ESMTPS id 656AD7803CD for ; Tue, 26 Mar 2024 22:57:32 +0000 (UTC) DKIM-Signature: a=rsa-sha256; bh=w9qiw1TNcKZkOwH26AGtGbgYBVMWPdvbgIB2nM17WKY=; c=relaxed/simple; d=groups.io; h=MIME-Version:References:In-Reply-To:From:Date:Message-ID:Subject:To:Cc:Precedence:List-Subscribe:List-Help:Sender:List-Id:Mailing-List:Delivered-To:Resent-Date:Reply-To:List-Unsubscribe-Post:List-Unsubscribe:Content-Type; s=20240206; t=1711493850; v=1; b=EvgI3YafHNLLOMnoFYqITGpBgIaiwWwZJvvUJTPWIE5JcViblaLwqhFXfZodzrRgc5nsv3CH PccPBW/2bzAhyK9YR/4xdkhnRLXDAdB2kYXDYqZiPI3zCnAhoCucOiUZAeoTSJC5+medhvbPl55 xPGMVizgKpfpB4fgva410WznRQJO1qH9o5mU5LxcrmFqwSi7HlwAhsPWgAwtANnlcrr8OZRgoBq FSt06kUlgkHsRGsx3djHxZw3MboEOqbUJAO9k4JMx0DgB6p/tsOVisfzxK63zvVncRySJvmfCYq doN50d1KqKhEkstRAwcfPvp2ijfBwb8dJmvZh+wGFqQ1Q== X-Received: by 127.0.0.2 with SMTP id dvdCYY7687511xiw14yPp19N; Tue, 26 Mar 2024 15:57:30 -0700 X-Received: from mail-lf1-f53.google.com (mail-lf1-f53.google.com [209.85.167.53]) by mx.groups.io with SMTP id smtpd.web10.24632.1711493849203164901 for ; Tue, 26 Mar 2024 15:57:30 -0700 X-Received: by mail-lf1-f53.google.com with SMTP id 2adb3069b0e04-513d3746950so7660775e87.1 for ; Tue, 26 Mar 2024 15:57:28 -0700 (PDT) X-Gm-Message-State: 702It8O3uLNuqPqE1q4lPB1Zx7686176AA= X-Google-Smtp-Source: AGHT+IFS1XXZQAfU1K0v9motcz1ZCF9D6/3diiMNiv4EH5HLpaUfwHPyRayUnZzd161WGI6w9IwL/lJVxM1cdo1GdAA= X-Received: by 2002:ac2:5b03:0:b0:511:674d:88c5 with SMTP id v3-20020ac25b03000000b00511674d88c5mr655450lfn.13.1711493846814; Tue, 26 Mar 2024 15:57:26 -0700 (PDT) MIME-Version: 1.0 References: <20240314145300.153086-1-nicklew@nvidia.com> <517B1BB3-9433-4C68-80F3-46BBC1627671@gmail.com> In-Reply-To: From: "Mike Maslenkin" Date: Wed, 27 Mar 2024 01:56:49 +0300 Message-ID: Subject: Re: [edk2-devel] [edk2-redfish-client][PATCH 1/2] RedfishClientPkg/Features: support Redfish Secure Boot To: Nickle Wang Cc: "devel@edk2.groups.io" , Abner Chang , Igor Kulchytskyy , Nick Ramirez Precedence: Bulk List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Resent-Date: Tue, 26 Mar 2024 15:57:30 -0700 Reply-To: devel@edk2.groups.io,mike.maslenkin@gmail.com List-Unsubscribe-Post: List-Unsubscribe=One-Click List-Unsubscribe: Content-Type: multipart/alternative; boundary="000000000000c65f1206149836c7" X-GND-Status: LEGIT Authentication-Results: spool.mail.gandi.net; dkim=pass header.d=groups.io header.s=20240206 header.b=EvgI3Yaf; dmarc=fail reason="SPF not aligned (relaxed), DKIM not aligned (relaxed)" header.from=gmail.com (policy=none); spf=pass (spool.mail.gandi.net: domain of bounce@groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce@groups.io --000000000000c65f1206149836c7 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Hi Nickle, On Tue, Mar 26, 2024 at 4:57=E2=80=AFPM Nickle Wang wr= ote: > Hi Mike, > > > > Thanks for your review. I addressed your review comments in pull request: > https://github.com/tianocore/edk2-redfish-client/pull/83 > > > > I am waiting for Abner=E2=80=99s patch (PR#84) because I plan to incorpor= ate > Abner=E2=80=99s changes into this driver. I will send version 2 patch ser= ies here > for review later. > > > > Regards, > > Nickle > > > I see my comments were addressed, and I agree with that. But I think I found another minor leaks in a common pattern: + if (PropertyChecker (SecureBootCs->SecureBootMode, ProvisionMode)) { + Status =3D GetSetupMode (&SetupMode); + if (!EFI_ERROR (Status)) { + AsciiStringValue =3D AllocateZeroPool (SECURE_BOOT_MODE_STR_LEN *sizeof (CHAR8)); + if (AsciiStringValue !=3D NULL) { + AsciiSPrint (AsciiStringValue, SECURE_BOOT_MODE_STR_LEN *sizeof (CHAR8), "%a", (SetupMode =3D=3D USER_MODE ? SECURE_BOOT_USER_MODE : SECURE_BOOT_SETUP_MODE)); + if (ProvisionMode || (AsciiStrCmp (SecureBootCs->SecureBootMode, AsciiStringValue) !=3D 0)) { + SecureBootCs->SecureBootMode =3D AsciiStringValue; + PropertyChanged =3D TRUE; + } + } + } else { + DEBUG ((DEBUG_ERROR, "%a: cannot read setup mode: %r\n", __func__, Status)); + } + } For the case when PropertyChanged left FALSE, allocated values AsciiStringV= alue and IntegerValue are leaked. Also there is a one new question below: > *From:* Mike Maslenkin > *Sent:* Friday, March 15, 2024 3:38 AM > *To:* devel@edk2.groups.io; Nickle Wang > *Cc:* Abner Chang ; Igor Kulchytskyy = ; > Nick Ramirez > *Subject:* Re: [edk2-devel] [edk2-redfish-client][PATCH 1/2] > RedfishClientPkg/Features: support Redfish Secure Boot > > > > *External email: Use caution opening links or attachments* > > > > Hi Nickle, > > > > please find my comments below > > > > On 14. 3. 2024., at 17:53, Nickle Wang via groups.io nvidia.com@groups.io> wrote: > > > > Introduce SecureBoot driver to support > /redfish/v1/Systems/SYS/SecureBoot resource. > > Signed-off-by: Nickle Wang > Cc: Abner Chang > Cc: Igor Kulchytskyy > Cc: Nick Ramirez > --- > .../RedfishClientComponents.dsc.inc | 2 + > RedfishClientPkg/RedfishClientLibs.dsc.inc | 4 + > .../SecureBoot/v1_1_0/Dxe/SecureBootDxe.inf | 60 ++ > .../v1_1_0/Common/SecureBootCommon.h | 40 + > .../v1_1_0/Common/SecureBootCommon.c | 756 ++++++++++++++++ > .../SecureBoot/v1_1_0/Dxe/SecureBootDxe.c | 808 ++++++++++++++++++ > RedfishClientPkg/RedfishClient.fdf.inc | 1 + > 7 files changed, 1671 insertions(+) > create mode 100644 > RedfishClientPkg/Features/SecureBoot/v1_1_0/Dxe/SecureBootDxe.inf > create mode 100644 > RedfishClientPkg/Features/SecureBoot/v1_1_0/Common/SecureBootCommon.h > create mode 100644 > RedfishClientPkg/Features/SecureBoot/v1_1_0/Common/SecureBootCommon.c > create mode 100644 > RedfishClientPkg/Features/SecureBoot/v1_1_0/Dxe/SecureBootDxe.c > > diff --git a/RedfishClientPkg/RedfishClientComponents.dsc.inc > b/RedfishClientPkg/RedfishClientComponents.dsc.inc > index ae2a4b025..42fc0c299 100644 > --- a/RedfishClientPkg/RedfishClientComponents.dsc.inc > +++ b/RedfishClientPkg/RedfishClientComponents.dsc.inc > @@ -34,6 +34,7 @@ > RedfishClientPkg/Features/Bios/v1_0_9/Dxe/BiosDxe.inf > > RedfishClientPkg/Features/BootOptionCollection/BootOptionCollectionDxe.= inf > RedfishClientPkg/Features/BootOption/v1_0_4/Dxe/BootOptionDxe.inf > + RedfishClientPkg/Features/SecureBoot/v1_1_0/Dxe/SecureBootDxe.inf > > !include RedfishClientPkg/RedfishJsonStructureDxe.dsc.inc > > @@ -47,3 +48,4 @@ > RedfishClientPkg/Converter/Bios/v1_0_9/RedfishBios_V1_0_9_Dxe.inf > > RedfishClientPkg/Converter/BootOptionCollection/RedfishBootOptionCollec= tion_Dxe.inf > > RedfishClientPkg/Converter/BootOption/v1_0_4/RedfishBootOption_V1_0_4_D= xe.inf > + > RedfishClientPkg/Converter/SecureBoot/v1_1_0/RedfishSecureBoot_V1_1_0_Dx= e.inf > diff --git a/RedfishClientPkg/RedfishClientLibs.dsc.inc > b/RedfishClientPkg/RedfishClientLibs.dsc.inc > index 6599926ab..9126465df 100644 > --- a/RedfishClientPkg/RedfishClientLibs.dsc.inc > +++ b/RedfishClientPkg/RedfishClientLibs.dsc.inc > @@ -25,6 +25,8 @@ > > BiosV1_0_9Lib|RedfishClientPkg/ConverterLib/edk2library/Bios/v1_0_9/Lib= .inf > > BootOptionCollectionLib|RedfishClientPkg/ConverterLib/edk2library/BootO= ptionCollection/Lib.inf > > BootOptionV1_0_4Lib|RedfishClientPkg/ConverterLib/edk2library/BootOptio= n/v1_0_4/Lib.inf > + > SecureBootV1_1_0Lib|RedfishClientPkg/ConverterLib/edk2library/SecureBoot= /v1_1_0/Lib.inf > + > # > # Above modules should be pulled in by build tool. > # > @@ -42,3 +44,5 @@ > > RedfishAddendumLib|RedfishClientPkg/Library/RedfishAddendumLib/RedfishA= ddendumLib.inf > RedfishDebugLib|RedfishPkg/Library/RedfishDebugLib/RedfishDebugLib.inf > RedfishHttpLib|RedfishPkg/Library/RedfishHttpLib/RedfishHttpLib.inf > + > SecureBootVariableLib|SecurityPkg/Library/SecureBootVariableLib/SecureBo= otVariableLib.inf > + > PlatformPKProtectionLib|SecurityPkg/Library/PlatformPKProtectionLibVarPo= licy/PlatformPKProtectionLibVarPolicy.inf > diff --git > a/RedfishClientPkg/Features/SecureBoot/v1_1_0/Dxe/SecureBootDxe.inf > b/RedfishClientPkg/Features/SecureBoot/v1_1_0/Dxe/SecureBootDxe.inf > new file mode 100644 > index 000000000..1ad8c623f > --- /dev/null > +++ b/RedfishClientPkg/Features/SecureBoot/v1_1_0/Dxe/SecureBootDxe.inf > @@ -0,0 +1,60 @@ > +## @file > +# > +# (C) Copyright 2020-2022 Hewlett Packard Enterprise Development LP
> +# Copyright (c) 2022-2024, NVIDIA CORPORATION & AFFILIATES. All rights > reserved. > +# > +# SPDX-License-Identifier: BSD-2-Clause-Patent > +# > +## > + > + > +[Defines] > + INF_VERSION =3D 0x00010005 > + BASE_NAME =3D SecureBootDxe > + FILE_GUID =3D 5E4025F8-DA42-468A-853E-6A1091D35052 > + MODULE_TYPE =3D DXE_DRIVER > + VERSION_STRING =3D 1.0 > + ENTRY_POINT =3D RedfishResourceEntryPoint > + UNLOAD_IMAGE =3D RedfishResourceUnload > + > +[Packages] > + MdePkg/MdePkg.dec > + MdeModulePkg/MdeModulePkg.dec > + SecurityPkg/SecurityPkg.dec > + RedfishPkg/RedfishPkg.dec > + RedfishClientPkg/RedfishClientPkg.dec > + > +[Sources] > + ../Common/SecureBootCommon.h > + ../Common/SecureBootCommon.c > + SecureBootDxe.c > + > +[LibraryClasses] > + BaseMemoryLib > + DebugLib > + EdkIIRedfishResourceConfigLib > + RedfishFeatureUtilityLib > + RedfishVersionLib > + RedfishResourceIdentifyLib > + SecureBootVariableLib > + UefiLib > + UefiDriverEntryPoint > + RedfishAddendumLib > > + UefiRuntimeServicesTableLib > + > +[Protocols] > + gEdkIIRedfishConfigHandlerProtocolGuid ## PRODUCED > + gEfiRestJsonStructureProtocolGuid ## CONSUMED > + gEdkIIRedfishResourceConfigProtocolGuid ## PRODUCED > + gEdkIIRedfishFeatureProtocolGuid ## CONSUMED > + > +[Guids] > + gEfiSecureBootEnableDisableGuid ## CONSUMED > + > +[Pcd] > + gEfiRedfishClientPkgTokenSpaceGuid.PcdMaxRedfishSchemaStringSize > + gEfiRedfishClientPkgTokenSpaceGuid.PcdMaxRedfishSchemaVersionSize > + gEfiRedfishClientPkgTokenSpaceGuid.PcdRedfishSystemRebootRequired > + > +[Depex] > + TRUE > diff --git > a/RedfishClientPkg/Features/SecureBoot/v1_1_0/Common/SecureBootCommon.h > b/RedfishClientPkg/Features/SecureBoot/v1_1_0/Common/SecureBootCommon.h > new file mode 100644 > index 000000000..0d1824160 > --- /dev/null > +++ b/RedfishClientPkg/Features/SecureBoot/v1_1_0/Common/SecureBootCommon= .h > @@ -0,0 +1,40 @@ > +/** @file > + > + Redfish feature driver implementation - internal header file > + (C) Copyright 2020-2022 Hewlett Packard Enterprise Development LP
> + Copyright (c) 2022-2024, NVIDIA CORPORATION & AFFILIATES. All rights > reserved. > + > + SPDX-License-Identifier: BSD-2-Clause-Patent > + > +**/ > + > +#ifndef EFI_REDFISH_SECUREBOOT_COMMON_H_ > +#define EFI_REDFISH_SECUREBOOT_COMMON_H_ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +// > +// Schema information. > +// > +#define REDFISH_MANAGED_URI L"Systems/{}/SecureBoot" > +#define REDFISH_DUMMY_CONFIG_LANG L"Systems/{1}/SecureBoot" > +#define MAX_URI_LENGTH 256 > +#define RESOURCE_SCHEMA "SecureBoot" > +#define RESOURCE_SCHEMA_MAJOR "1" > +#define RESOURCE_SCHEMA_MINOR "1" > +#define RESOURCE_SCHEMA_ERRATA "0" > +#define RESOURCE_SCHEMA_VERSION "v1_1_0" > +#define SECURE_BOOT_SETUP_MODE "SetupMode" > +#define SECURE_BOOT_USER_MODE "UserMode" > +#define SECURE_BOOT_ENABLED "Enabled" > +#define SECURE_BOOT_DISABLED "Disabled" > +#define SECURE_BOOT_MODE_STR_LEN 16 > + > +#endif > diff --git > a/RedfishClientPkg/Features/SecureBoot/v1_1_0/Common/SecureBootCommon.c > b/RedfishClientPkg/Features/SecureBoot/v1_1_0/Common/SecureBootCommon.c > new file mode 100644 > index 000000000..56a45ee72 > --- /dev/null > +++ b/RedfishClientPkg/Features/SecureBoot/v1_1_0/Common/SecureBootCommon= .c > @@ -0,0 +1,756 @@ > +/** @file > + Redfish feature driver implementation - common functions > + > + (C) Copyright 2020-2022 Hewlett Packard Enterprise Development LP
> + Copyright (c) 2023-2024, NVIDIA CORPORATION & AFFILIATES. All rights > reserved. > + > + SPDX-License-Identifier: BSD-2-Clause-Patent > + > +**/ > + > +#include "SecureBootCommon.h" > + > +CHAR8 SecureBootEmptyJson[] =3D "{\"@odata.id\": \"\", \"@odata.type\": > \"#SecureBoot.v1_1_0.SecureBoot\", \"Id\": \"\", \"Name\": \"\", > \"Attributes\":{}}"; > + > +REDFISH_RESOURCE_COMMON_PRIVATE *mRedfishResourcePrivate > =3D NULL; > +EFI_HANDLE mRedfishResourceConfigProtocolHandle > =3D NULL; > +CHAR16 > *mSecureBootSupportedAttributes[SECURE_BOOT_MOD= E_STR_LEN] > =3D { > + L"SecureBootCurrentBoot", > + L"SecureBootEnable", > + L"SecureBootMode" > +}; > + > +/** > + Read EFI_SECURE_BOOT_ENABLE_NAME variable and return its value to > caller. > + > + @retval BOOLEAN TRUE when EFI_SECURE_BOOT_ENABLE_NAME value is > SECURE_BOOT_ENABLE > + FALSE when EFI_SECURE_BOOT_ENABLE_NAME value is > SECURE_BOOT_DISABLE > +**/ > +BOOLEAN > +RedfishReadSecureBootEnable ( > + VOID > + ) > +{ > + UINT8 *Buffer; > + BOOLEAN SecureBootEnableValue; > + > + Buffer =3D NULL; > + SecureBootEnableValue =3D FALSE; > + > + GetVariable2 ( > + EFI_SECURE_BOOT_ENABLE_NAME, > + &gEfiSecureBootEnableDisableGuid, > + (VOID **)&Buffer, > + NULL > + ); > + > + if (Buffer !=3D NULL) { > + if (*Buffer =3D=3D SECURE_BOOT_ENABLE) { > + SecureBootEnableValue =3D TRUE; > + } > + > + FreePool (Buffer); > + } > + > + return SecureBootEnableValue; > +} > + > +/** > + Write EFI_SECURE_BOOT_ENABLE_NAME variable with given value. > + > + @param[in] SecureBootEnableValue Value to write. TRUE is > SECURE_BOOT_ENABLE. > + FALSE is SECURE_BOOT_DISABLE. > + > + @retval EFI_SUCCESS Write value successfully. > + @retval Others Some error happened. > +**/ > +EFI_STATUS > +RedfishWriteSecureBootEnable ( > + BOOLEAN SecureBootEnableValue > + ) > +{ > + EFI_STATUS Status; > + UINT8 VarValue; > + > + VarValue =3D (SecureBootEnableValue ? SECURE_BOOT_ENABLE : > SECURE_BOOT_DISABLE); > + Status =3D gRT->SetVariable ( > + EFI_SECURE_BOOT_ENABLE_NAME, > + &gEfiSecureBootEnableDisableGuid, > + EFI_VARIABLE_NON_VOLATILE | > EFI_VARIABLE_BOOTSERVICE_ACCESS, > + sizeof (VarValue), > + &VarValue > + ); > + > + return Status; > +} > + > +/** > + Consume Redfish resource in given Json data. > + > + @param[in] This Pointer to > REDFISH_RESOURCE_COMMON_PRIVATE instance. > + @param[in] Json The JSON to consume. > + @param[in] HeaderEtag The Etag string returned in HTTP > header. > + > + @retval EFI_SUCCESS Consume Redfish attribute successfull= y. > + @retval Others Some error happened. > + > +**/ > +EFI_STATUS > +RedfishConsumeResourceCommon ( > + IN REDFISH_RESOURCE_COMMON_PRIVATE *Private, > + IN CHAR8 *Json, > + IN CHAR8 *HeaderEtag OPTIONAL > + ) > +{ > + EFI_STATUS Status; > + EFI_REDFISH_SECUREBOOT_V1_1_0 *SecureBoot; > + EFI_REDFISH_SECUREBOOT_V1_1_0_CS *SecureBootCs; > + BOOLEAN SecureBootEnableDisable; > + > + if ((Private =3D=3D NULL) || IS_EMPTY_STRING (Json)) { > + return EFI_INVALID_PARAMETER; > + } > + > + SecureBoot =3D NULL; > + SecureBootCs =3D NULL; > + SecureBootEnableDisable =3D RedfishReadSecureBootEnable (); > + > + Status =3D Private->JsonStructProtocol->ToStructure ( > + Private->JsonStructProtocol, > + NULL, > + Json, > + (EFI_REST_JSON_STRUCTURE_HEADE= R > **)&SecureBoot > + ); > + if (EFI_ERROR (Status)) { > + DEBUG ((DEBUG_ERROR, "%a: ToStructure() failed: %r\n", __func__, > Status)); > + return Status; > + } > + > + SecureBootCs =3D SecureBoot->SecureBoot; > + > + // > + // Check ETAG to see if we need to consume it > + // > + if (CheckEtag (Private->Uri, HeaderEtag, SecureBootCs->odata_etag)) { > + // > + // No change > + // > + DEBUG ((REDFISH_DEBUG_TRACE, "%a: ETAG: %s has no change, ignore > consume action\n", __func__, Private->Uri)); > + Status =3D EFI_ALREADY_STARTED; > + goto ON_RELEASE; > + } > + > + // > + // Secure boot enable > + // > + if (SecureBootCs->SecureBootEnable !=3D NULL) { > + if (SecureBootEnableDisable !=3D *SecureBootCs->SecureBootEnable) { > + // > + // Write value to "SecureBootEnable" variable. AuthVariableLib wil= l > enable or disable secure boot > + // based on "SecureBootEnable" value. > + // > + Status =3D RedfishWriteSecureBootEnable > (*SecureBootCs->SecureBootEnable); > + if (EFI_ERROR (Status)) { > + DEBUG ((DEBUG_ERROR, "%a: write secure boot enable disable > failed: %r\n", __func__, Status)); > + } else { > + REDFISH_ENABLE_SYSTEM_REBOOT (); > + } > + } else { > + DEBUG ((REDFISH_DEBUG_TRACE, "%a: secure boot mode is not > changed\n", __func__)); > + } > + } > + > +ON_RELEASE: > + > + // > + // Release resource. > + // > + Private->JsonStructProtocol->DestoryStructure ( > + Private->JsonStructProtocol, > + (EFI_REST_JSON_STRUCTURE_HEADER > *)SecureBoot > + ); > + > + return EFI_SUCCESS; > +} > + > +/** > + Provision Redfish resource. This function reads secure boot variable > and convert it > + to Redfish attribute. > + > + @param[in] JsonStructProtocol Pointer to Json structure protocol. > + @param[in] InputJson Jason data on input. > + @param[in] ResourceId Resource ID. This is optional. > + @param[in] ConfigureLang Configure language for this Redfish > resource. > + @param[in] ProvisionMode TRUE when this is to provision Redfis= h > attribute to > + Redfish service. FALSE is to update > Redfish attribute > + to Redfish service. > + @param[out] ResultJson Json data on output. > + > + @retval EFI_SUCCESS Provision Redfish attribute > successfully. > + @retval Others Some error happened. > + > +**/ > +EFI_STATUS > +ProvisioningSecureBootProperties ( > + IN EFI_REST_JSON_STRUCTURE_PROTOCOL *JsonStructProtocol, > + IN CHAR8 *InputJson, > + IN CHAR8 *ResourceId OPTIONAL, > + IN EFI_STRING ConfigureLang, > + IN BOOLEAN ProvisionMode, > + OUT CHAR8 **ResultJson > + ) > +{ > + EFI_REDFISH_SECUREBOOT_V1_1_0 *SecureBoot; > + EFI_REDFISH_SECUREBOOT_V1_1_0_CS *SecureBootCs; > + EFI_STATUS Status; > + BOOLEAN PropertyChanged; > + CHAR8 *AsciiStringValue; > + INT32 *IntegerValue; > + UINT8 SetupMode; > + BOOLEAN SecureBootEnabled; > + BOOLEAN SecureBootEnableDisable; > + > + if ((JsonStructProtocol =3D=3D NULL) || (ResultJson =3D=3D NULL) || > IS_EMPTY_STRING (InputJson) || IS_EMPTY_STRING (ConfigureLang)) { > + return EFI_INVALID_PARAMETER; > + } > + > + DEBUG ((REDFISH_DEBUG_TRACE, "%a provision for %s with: %s\n", > __func__, ConfigureLang, (ProvisionMode ? L"Provision resource" : L"Updat= e > resource"))); > + > + *ResultJson =3D NULL; > + PropertyChanged =3D FALSE; > + AsciiStringValue =3D NULL; > + SecureBootEnableDisable =3D RedfishReadSecureBootEnable (); > + SecureBootEnabled =3D IsSecureBootEnabled (); > + > + SecureBoot =3D NULL; > + Status =3D JsonStructProtocol->ToStructure ( > + JsonStructProtocol, > + NULL, > + InputJson, > + (EFI_REST_JSON_STRUCTURE_HEADER > **)&SecureBoot > + ); > + if (EFI_ERROR (Status)) { > + DEBUG ((DEBUG_ERROR, "%a: ToStructure failure: %r\n", __func__, > Status)); > + return Status; > + } > + > + SecureBootCs =3D SecureBoot->SecureBoot; > + > + // > + // ID > + // > + if (SecureBootCs->Id !=3D NULL) { > + SecureBootCs->Id =3D NULL; > + } > + > + // > + // Name > + // > + if (SecureBootCs->Name !=3D NULL) { > + SecureBootCs->Name =3D NULL; > + } > + > + // > + // Secure boot variables that we will handle here > + // > + // EFI_SETUP_MODE_NAME (gEfiGlobalVariableGuid) > + // EFI_SECURE_BOOT_MODE_NAME (gEfiGlobalVariableGuid) > + // EFI_SECURE_BOOT_ENABLE_NAME (gEfiSecureBootEnableDisableGuid) > + // > + > + // > + // Current Boot > + // > + if (PropertyChecker (SecureBootCs->SecureBootCurrentBoot, > ProvisionMode)) { > + AsciiStringValue =3D AllocateZeroPool (SECURE_BOOT_MODE_STR_LEN * > sizeof (CHAR8)); > + if (AsciiStringValue !=3D NULL) { > + AsciiSPrint (AsciiStringValue, SECURE_BOOT_MODE_STR_LEN, "%a", > (SecureBootEnabled ? SECURE_BOOT_ENABLED : SECURE_BOOT_DISABLED)); > + if (ProvisionMode || (AsciiStrCmp > (SecureBootCs->SecureBootCurrentBoot, AsciiStringValue) !=3D 0)) { > + SecureBootCs->SecureBootCurrentBoot =3D AsciiStringValue; > + PropertyChanged =3D TRUE; > + } > + } else { > + DEBUG ((DEBUG_ERROR, "%a: out of resource\n", __func__)); > + } > + } > + > + // > + // Secure boot enable > + // > + if (PropertyChecker (SecureBootCs->SecureBootEnable, ProvisionMode)) { > + if (ProvisionMode || (*SecureBootCs->SecureBootEnable !=3D > SecureBootEnableDisable)) { > + IntegerValue =3D AllocatePool (sizeof (*IntegerValue)); > + if (IntegerValue !=3D NULL) { > + *IntegerValue =3D (SecureBootEnableDisable ? 0x= 01 > : 0x00); > + SecureBootCs->SecureBootEnable =3D IntegerValue; > + PropertyChanged =3D TRUE; > + } else { > + DEBUG ((DEBUG_ERROR, "%a: out of resource\n", __func__)); > + } > + } > + } > + > + // > + // Secure boot mode > + // > + if (PropertyChecker (SecureBootCs->SecureBootMode, ProvisionMode)) { > + Status =3D GetSetupMode (&SetupMode); > + if (!EFI_ERROR (Status)) { > + AsciiStringValue =3D AllocateZeroPool (SECURE_BOOT_MODE_STR_LEN > *sizeof (CHAR8)); > + if (AsciiStringValue !=3D NULL) { > + AsciiSPrint (AsciiStringValue, SECURE_BOOT_MODE_STR_LEN *sizeof > (CHAR8), "%a", (SetupMode =3D=3D USER_MODE ? SECURE_BOOT_USER_MODE : > SECURE_BOOT_SETUP_MODE)); > + if (ProvisionMode || (AsciiStrCmp (SecureBootCs->SecureBootMode, > AsciiStringValue) !=3D 0)) { > + SecureBootCs->SecureBootMode =3D AsciiStringValue; > + PropertyChanged =3D TRUE; > + } > + } > + } else { > + DEBUG ((DEBUG_ERROR, "%a: cannot read setup mode: %r\n", __func__, > Status)); > + } > + } > + > + // > + // Convert C structure back to JSON text. > + // > + Status =3D JsonStructProtocol->ToJson ( > + JsonStructProtocol, > + (EFI_REST_JSON_STRUCTURE_HEADER > *)SecureBoot, > + ResultJson > + ); > + if (EFI_ERROR (Status)) { > + DEBUG ((DEBUG_ERROR, "%a: ToJson() failed: %r\n", __func__, Status))= ; > + return Status; > > > > > > > > SecureBoot structure leak. It is released below. > > > > + } > + > + // > + // Release resource. > + // > + JsonStructProtocol->DestoryStructure ( > + JsonStructProtocol, > + (EFI_REST_JSON_STRUCTURE_HEADER *)SecureBoot > + ); > + > + return (PropertyChanged ? EFI_SUCCESS : EFI_NOT_FOUND); > +} > + > +/** > + Provision Redfish resource and upload data to Redfish service. This > function > + checks OEM data and platform addendum data before sending data to > Redfish service. > + > + @param[in] Private Pointer to private data. > + > + @retval EFI_SUCCESS Provision Redfish resource > successfully. > + @retval Others Some error happened. > + > +**/ > +EFI_STATUS > +ProvisioningSecureBootResource ( > + IN REDFISH_RESOURCE_COMMON_PRIVATE *Private > + ) > +{ > + EFI_STATUS Status; > + CHAR8 *Json; > + CHAR8 *JsonWithAddendum; > + REDFISH_RESPONSE Response; > + > + if (Private =3D=3D NULL) { > + return EFI_INVALID_PARAMETER; > + } > + > + ZeroMem (&Response, sizeof (REDFISH_RESPONSE)); > + Json =3D NULL; > + > + Status =3D ProvisioningSecureBootProperties ( > + Private->JsonStructProtocol, > + SecureBootEmptyJson, > + NULL, > + REDFISH_DUMMY_CONFIG_LANG, > + TRUE, > + &Json > + ); > + if (EFI_ERROR (Status)) { > + if (Status =3D=3D EFI_NOT_FOUND) { > + DEBUG ((REDFISH_DEBUG_TRACE, "%a: provisioning existing resource > for %s ignored. Nothing changed\n", __func__, REDFISH_DUMMY_CONFIG_LANG))= ; > + Status =3D EFI_SUCCESS; > + } else { > + DEBUG ((DEBUG_ERROR, "%a: provisioning existing resource for %s > failed: %r\n", __func__, REDFISH_DUMMY_CONFIG_LANG, Status)); > + } > + > + goto ON_RELEASE; > + } > + > + // > + // Check and see if platform has OEM data or not > + // > + Status =3D RedfishGetOemData ( > + Private->Uri, > + RESOURCE_SCHEMA, > + RESOURCE_SCHEMA_VERSION, > + Json, > + &JsonWithAddendum > + ); > + if (!EFI_ERROR (Status) && (JsonWithAddendum !=3D NULL)) { > + FreePool (Json); > + Json =3D JsonWithAddendum; > + JsonWithAddendum =3D NULL; > + } > + > + // > + // Check and see if platform has addendum data or not > + // > + Status =3D RedfishGetAddendumData ( > + Private->Uri, > + RESOURCE_SCHEMA, > + RESOURCE_SCHEMA_VERSION, > + Json, > + &JsonWithAddendum > + ); > + if (!EFI_ERROR (Status) && (JsonWithAddendum !=3D NULL)) { > + FreePool (Json); > + Json =3D JsonWithAddendum; > + JsonWithAddendum =3D NULL; > + } > + > + DEBUG ((REDFISH_DEBUG_TRACE, "%a: provisioning existing resource for > %s\n", __func__, REDFISH_DUMMY_CONFIG_LANG)); > + > + // > + // PATCH back to instance > + // > + Status =3D RedfishHttpPatchResource (Private->RedfishService, > Private->Uri, Json, &Response); > + if (EFI_ERROR (Status)) { > + DEBUG ((DEBUG_ERROR, "%a: patch resource for %s failed: %r\n", > __func__, REDFISH_DUMMY_CONFIG_LANG, Status)); > + } > + > +ON_RELEASE: > + > + if (Json !=3D NULL) { > + FreePool (Json); > + } > + > + RedfishHttpFreeResponse (&Response); > + > + return Status; > +} > + > +/** > + Provisioning redfish resource to Redfish service. > + > + @param[in] Private Pointer to private data. > + @param[in] ResourceExist TRUE if resource exists, PUT method > will be used. > + FALSE if resource does not exist POST > method is used. > > > > > > Actually ProvisioningSecureBootResource uses PATCH only. > > > > > > + > + @retval EFI_SUCCESS Provision resource successfully. > + @retval Others Some error happened. > + > +**/ > +EFI_STATUS > +RedfishProvisioningResourceCommon ( > + IN REDFISH_RESOURCE_COMMON_PRIVATE *Private, > + IN BOOLEAN ResourceExist > + ) > +{ > + if (Private =3D=3D NULL) { > + return EFI_INVALID_PARAMETER; > + } > + > + return ProvisioningSecureBootResource (Private); > +} > + > +/** > + Check resource from given Json data. > + > + @param[in] This Pointer to > REDFISH_RESOURCE_COMMON_PRIVATE instance. > + @param[in] Json The JSON data to check. > + @param[in] HeaderEtag The Etag string returned in HTTP > header. > + > + @retval EFI_SUCCESS Check resource successfully. > + @retval Others Some error happened. > + > +**/ > +EFI_STATUS > +RedfishCheckResourceCommon ( > + IN REDFISH_RESOURCE_COMMON_PRIVATE *Private, > + IN CHAR8 *Json, > + IN CHAR8 *HeaderEtag OPTIONAL > + ) > +{ > + UINTN Index; > + EFI_STATUS Status; > + UINTN Count; > + EFI_STRING Property; > + > + if ((Private =3D=3D NULL) || IS_EMPTY_STRING (Json)) { > + return EFI_INVALID_PARAMETER; > + } > + > + // > + // Check ETAG to see if we need to check it > + // > + if (CheckEtag (Private->Uri, HeaderEtag, NULL)) { > + // > + // No change > + // > + DEBUG ((REDFISH_DEBUG_TRACE, "%a: ETAG: %s has no change, ignore > check action\n", __func__, Private->Uri)); > + return EFI_SUCCESS; > + } > + > + Count =3D sizeof (mSecureBootSupportedAttributes) / sizeof > (mSecureBootSupportedAttributes[0]); > + if (Count =3D=3D 0) { > + return EFI_UNSUPPORTED; > + } > + > + Status =3D EFI_SUCCESS; > + for (Index =3D 0; Index < Count; Index++) { > + Property =3D mSecureBootSupportedAttributes[Index]; > + if (Property =3D=3D NULL) { > + continue; > + } > + > + DEBUG ((REDFISH_DEBUG_TRACE, "%a: [%d] check attribute for: %s\n", > __func__, Index, Property)); > + if (!MatchPropertyWithJsonContext (Property, Json)) { > + DEBUG ((REDFISH_DEBUG_TRACE, "%a: property is missing: %s\n", > __func__, Property)); > + Status =3D EFI_NOT_FOUND; > > Oh! I have a question about this condition. Can we just break the loop here? I'm asking mostly in context of Bios feature driver where the same loop exists. While in this driver Count not greater than 3, but for Bios driver there could be a hundreds of iterations and AFAIR during provisioning we have EFI_NOT_FOUND right after the first iteration. MatchPropertyWithJsonContext() seems to be a heavy call. The only useful thing this loop does in that case is printing missed property if enabled. + } > + } > + > > + return Status; > +} > + > +/** > + Update resource to Redfish service. > + > + @param[in] Private Pointer to > REDFISH_RESOURCE_COMMON_PRIVATE instance. > + @param[in] Json The JSON data to be updated. > + > + @retval EFI_SUCCESS Update resource successfully. > + @retval Others Some error happened. > + > +**/ > +EFI_STATUS > +RedfishUpdateResourceCommon ( > + IN REDFISH_RESOURCE_COMMON_PRIVATE *Private, > + IN CHAR8 *InputJson > + ) > +{ > + EFI_STATUS Status; > + CHAR8 *Json; > + CHAR8 *JsonWithAddendum; > + REDFISH_RESPONSE Response; > + > + if ((Private =3D=3D NULL) || IS_EMPTY_STRING (InputJson)) { > + return EFI_INVALID_PARAMETER; > + } > + > + ZeroMem (&Response, sizeof (REDFISH_RESPONSE)); > + Json =3D NULL; > + > + Status =3D ProvisioningSecureBootProperties ( > + Private->JsonStructProtocol, > + SecureBootEmptyJson, > + NULL, > + REDFISH_DUMMY_CONFIG_LANG, > + TRUE, > + &Json > + ); > + if (EFI_ERROR (Status)) { > + if (Status =3D=3D EFI_NOT_FOUND) { > + DEBUG ((REDFISH_DEBUG_TRACE, "%a: update resource for %s ignored. > Nothing changed\n", __func__, REDFISH_DUMMY_CONFIG_LANG)); > + Status =3D EFI_SUCCESS; > + } else { > + DEBUG ((DEBUG_ERROR, "%a: update resource for %s failed: %r\n", > __func__, REDFISH_DUMMY_CONFIG_LANG, Status)); > + } > + > + goto ON_RELEASE; > + } > + > + // > + // Check and see if platform has OEM data or not > + // > + Status =3D RedfishGetOemData ( > + Private->Uri, > + RESOURCE_SCHEMA, > + RESOURCE_SCHEMA_VERSION, > + Json, > + &JsonWithAddendum > + ); > + if (!EFI_ERROR (Status) && (JsonWithAddendum !=3D NULL)) { > + FreePool (Json); > + Json =3D JsonWithAddendum; > + JsonWithAddendum =3D NULL; > + } > + > + // > + // Check and see if platform has addendum data or not > + // > + Status =3D RedfishGetAddendumData ( > + Private->Uri, > + RESOURCE_SCHEMA, > + RESOURCE_SCHEMA_VERSION, > + Json, > + &JsonWithAddendum > + ); > + if (!EFI_ERROR (Status) && (JsonWithAddendum !=3D NULL)) { > + FreePool (Json); > + Json =3D JsonWithAddendum; > + JsonWithAddendum =3D NULL; > + } > + > + DEBUG ((REDFISH_DEBUG_TRACE, "%a: update resource for %s\n", __func__, > REDFISH_DUMMY_CONFIG_LANG)); > + > + // > + // PATCH back to instance > + // > + Status =3D RedfishHttpPatchResource (Private->RedfishService, > Private->Uri, Json, &Response); > + if (EFI_ERROR (Status)) { > + DEBUG ((DEBUG_ERROR, "%a: patch resource for %s failed: %r\n", > __func__, REDFISH_DUMMY_CONFIG_LANG, Status)); > + } > + > +ON_RELEASE: > + > + if (Json !=3D NULL) { > + FreePool (Json); > + } > + > + RedfishHttpFreeResponse (&Response); > + > + return Status; > +} > + > +/** > + Identify resource in given Json data. > + > + @param[in] Private Pointer to > REDFISH_RESOURCE_COMMON_PRIVATE instance. > + @param[in] Json The JSON to be identified. > + > + @retval EFI_SUCCESS Identify resource successfully. > + @retval Others Some error happened. > + > +**/ > +EFI_STATUS > +RedfishIdentifyResourceCommon ( > + IN REDFISH_RESOURCE_COMMON_PRIVATE *Private, > + IN CHAR8 *Json > + ) > +{ > + BOOLEAN Supported; > + > + Supported =3D RedfishIdentifyResource (Private->Uri, Private->Json); > + if (Supported) { > + // > + // Keep URI and ConfigLang mapping > + // > + RedfishSetRedfishUri (REDFISH_DUMMY_CONFIG_LANG, Private->Uri); > + } > + > + return (Supported ? EFI_SUCCESS : EFI_UNSUPPORTED); > +} > + > +/** > + Handle Redfish resource in Uri. > + > + @param[in] Private Pointer to > REDFISH_RESOURCE_COMMON_PRIVATE instance. > + @param[in] Uri URI to Redfish resource that we like > to process. > + > + @retval EFI_SUCCESS Handle resource successfully. > + @retval Others Some error happened. > + > +**/ > +EFI_STATUS > +HandleResource ( > + IN REDFISH_RESOURCE_COMMON_PRIVATE *Private, > + IN EFI_STRING Uri > + ) > +{ > + EFI_STATUS Status; > + REDFISH_SCHEMA_INFO SchemaInfo; > + EFI_STRING ConfigLang; > + > + if ((Private =3D=3D NULL) || IS_EMPTY_STRING (Uri)) { > + return EFI_INVALID_PARAMETER; > + } > + > + // > + // Resource match > + // > + > + DEBUG ((REDFISH_DEBUG_TRACE, "%a: process resource for: %s\n", > __func__, Uri)); > + > + Status =3D GetRedfishSchemaInfo (Private->RedfishService, > Private->JsonStructProtocol, Uri, NULL, &SchemaInfo); > + if (EFI_ERROR (Status)) { > + DEBUG ((DEBUG_ERROR, "%a: failed to get schema information from: %s > %r\n", __func__, Uri, Status)); > + return Status; > + } > + > + // > + // Check and see if this is target resource that we want to handle. > + // Some resource is handled by other provider so we have to make sure > this first. > + // > + DEBUG ((REDFISH_DEBUG_TRACE, "%a: Identify for %s\n", __func__, Uri)); > + ConfigLang =3D RedfishGetConfigLanguage (Uri); > + if (ConfigLang =3D=3D NULL) { > + Status =3D EdkIIRedfishResourceConfigIdentify (&SchemaInfo, Uri, NUL= L, > Private->InformationExchange); > + if (EFI_ERROR (Status)) { > + if (Status =3D=3D EFI_UNSUPPORTED) { > + DEBUG ((REDFISH_DEBUG_TRACE, "%a: \"%s\" is not handled by us\n"= , > __func__, Uri)); > + return EFI_SUCCESS; > + } else if (Status =3D=3D EFI_NOT_FOUND) { > + DEBUG ((REDFISH_DEBUG_TRACE, "%a: \"%s\" has nothing to > handle\n", __func__, Uri)); > + return EFI_SUCCESS; > + } > + > + DEBUG ((DEBUG_ERROR, "%a: fail to identify resource: \"%s\": %r\n"= , > __func__, Uri, Status)); > + return Status; > + } > + } else { > + DEBUG ((REDFISH_DEBUG_TRACE, "%a: history record found: %s\n", > __func__, ConfigLang)); > + FreePool (ConfigLang); > + } > + > + // > + // Check and see if target property exist or not even when collection > member exists. > + // If not, we sill do provision. > > > > %s/sill/still > > > > + // > + DEBUG ((REDFISH_DEBUG_TRACE, "%a Check for %s\n", __func__, Uri)); > + Status =3D EdkIIRedfishResourceConfigCheck (&SchemaInfo, Uri, NULL); > + if (EFI_ERROR (Status)) { > + if (Status =3D=3D EFI_UNSUPPORTED) { > + DEBUG ((REDFISH_DEBUG_TRACE, "%a: \"%s\" is not handled by us\n", > __func__, Uri)); > + return EFI_SUCCESS; > + } > + > + // > + // The target property does not exist, do the provision to create > property. > + // > + DEBUG ((REDFISH_DEBUG_TRACE, "%a provision for %s\n", __func__, Uri)= ); > + Status =3D EdkIIRedfishResourceConfigProvisioning (&SchemaInfo, Uri, > NULL, Private->InformationExchange, FALSE); > + if (EFI_ERROR (Status)) { > + DEBUG ((DEBUG_ERROR, "%a: failed to provision with GET mode: %r\n"= , > __func__, Status)); > + } > + > + DEBUG ((REDFISH_DEBUG_TRACE, "%a: process resource for: %s > finished\n", __func__, Uri)); > + > + return Status; > + } > + > + // > + // Consume first. > + // > + DEBUG ((REDFISH_DEBUG_TRACE, "%a consume for %s\n", __func__, Uri)); > + Status =3D EdkIIRedfishResourceConfigConsume (&SchemaInfo, Uri, NULL); > + if (EFI_ERROR (Status)) { > + DEBUG ((DEBUG_ERROR, "%a: failed to consume resource for: %s: %r\n", > __func__, Uri, Status)); > + } > + > + // > + // Patch. > + // > + DEBUG ((REDFISH_DEBUG_TRACE, "%a update for %s\n", __func__, Uri)); > + Status =3D EdkIIRedfishResourceConfigUpdate (&SchemaInfo, Uri, NULL); > + if (EFI_ERROR (Status)) { > + DEBUG ((DEBUG_ERROR, "%a: failed to update resource for: %s: %r\n", > __func__, Uri, Status)); > + } > + > + DEBUG ((REDFISH_DEBUG_TRACE, "%a: process resource for: %s finished\n"= , > __func__, Uri)); > + > + return Status; > +} > diff --git > a/RedfishClientPkg/Features/SecureBoot/v1_1_0/Dxe/SecureBootDxe.c > b/RedfishClientPkg/Features/SecureBoot/v1_1_0/Dxe/SecureBootDxe.c > new file mode 100644 > index 000000000..a0f4f3d14 > --- /dev/null > +++ b/RedfishClientPkg/Features/SecureBoot/v1_1_0/Dxe/SecureBootDxe.c > @@ -0,0 +1,808 @@ > +/** @file > + Redfish feature driver implementation - SecureBoot > + > + (C) Copyright 2020-2022 Hewlett Packard Enterprise Development LP
> + Copyright (c) 2023, NVIDIA CORPORATION & AFFILIATES. All rights > reserved. > + > + SPDX-License-Identifier: BSD-2-Clause-Patent > + > +**/ > + > +#include "../Common/SecureBootCommon.h" > + > +extern REDFISH_RESOURCE_COMMON_PRIVATE *mRedfishResourcePrivate; > +extern EFI_HANDLE > mRedfishResourceConfigProtocolHandle; > + > +EFI_STATUS > +HandleResource ( > + IN REDFISH_RESOURCE_COMMON_PRIVATE *Private, > + IN EFI_STRING Uri > + ); > + > +/** > + Provisioning redfish resource by given URI. > + > + @param[in] This Pointer to EFI_HP_REDFISH_HII_PROTOCO= L > instance. > + @param[in] Uri Target URI to create resource. > + @param[in] PostMode TRUE if the resource does not exist, > post method is used. > + FALSE if the resource exist but > property is missing, put method is used. > + > + @retval EFI_SUCCESS Value is returned successfully. > + @retval Others Some error happened. > + > +**/ > +EFI_STATUS > +EFIAPI > +RedfishResourceProvisioningResource ( > + IN EDKII_REDFISH_RESOURCE_CONFIG_PROTOCOL *This, > + IN EFI_STRING Uri, > + IN BOOLEAN PostMode > + ) > +{ > + REDFISH_RESOURCE_COMMON_PRIVATE *Private; > + EFI_STATUS Status; > + REDFISH_RESPONSE Response; > + > + if ((This =3D=3D NULL) || IS_EMPTY_STRING (Uri)) { > + return EFI_INVALID_PARAMETER; > + } > + > + DEBUG ((REDFISH_DEBUG_TRACE, "%a: provisioning in %s mode\n", __func__= , > (PostMode ? L"POST" : L"PATCH"))); > > > > > > This message conflicts with PostMode parameter description. > > > > > > + > + ZeroMem (&Response, sizeof (REDFISH_RESPONSE)); > + Private =3D REDFISH_RESOURCE_COMMON_PRIVATE_DATA_FROM_RESOURCE_PROTOCO= L > (This); > + > + if (Private->RedfishService =3D=3D NULL) { > + return EFI_NOT_READY; > + } > + > + Status =3D RedfishHttpGetResource (Private->RedfishService, Uri, NULL, > &Response, TRUE); > + if (EFI_ERROR (Status)) { > + DEBUG ((DEBUG_ERROR, "%a: get resource from: %s failed\n", __func__, > Uri)); > + return Status; > + } > + > + Private->Uri =3D Uri; > + Private->Payload =3D Response.Payload; > + ASSERT (Private->Payload !=3D NULL); > + > + Status =3D RedfishProvisioningResourceCommon (Private, !PostMode); > + if (EFI_ERROR (Status)) { > + DEBUG ((DEBUG_ERROR, "%a: failed to provision resource to: %s: %r\n"= , > __func__, Uri, Status)); > + } else { > + // > + // Get latest ETag on URI and keep it in variable. > + // > + SetEtagFromUri (Private->RedfishService, Private->Uri, TRUE); > + } > + > + // > + // Release resource > + // > + RedfishHttpFreeResponse (&Response); > + Private->Payload =3D NULL; > + > + return Status; > +} > + > +/** > + Consume resource from given URI. > + > + @param[in] This Pointer to EFI_HP_REDFISH_HII_PROTOCO= L > instance. > + @param[in] Uri The target URI to consume. > + > + @retval EFI_SUCCESS Value is returned successfully. > + @retval Others Some error happened. > + > +**/ > +EFI_STATUS > +EFIAPI > +RedfishResourceConsumeResource ( > + IN EDKII_REDFISH_RESOURCE_CONFIG_PROTOCOL *This, > + IN EFI_STRING Uri > + ) > +{ > + REDFISH_RESOURCE_COMMON_PRIVATE *Private; > + EFI_STATUS Status; > + REDFISH_RESPONSE Response; > + EFI_STRING PendingSettingUri; > + REDFISH_RESPONSE PendingSettingResponse; > + REDFISH_RESPONSE *ExpectedResponse; > + CHAR8 *Etag; > + > + if ((This =3D=3D NULL) || IS_EMPTY_STRING (Uri)) { > + return EFI_INVALID_PARAMETER; > + } > + > + ZeroMem (&Response, sizeof (REDFISH_RESPONSE)); > + ZeroMem (&PendingSettingResponse, sizeof (REDFISH_RESPONSE)); > + Private =3D REDFISH_RESOURCE_COMMON_PRIVATE_DATA_FROM_RESOURCE_PROTOCO= L > (This); > + > + if (Private->RedfishService =3D=3D NULL) { > + return EFI_NOT_READY; > + } > + > + Status =3D RedfishHttpGetResource (Private->RedfishService, Uri, NULL, > &Response, TRUE); > + if (EFI_ERROR (Status)) { > + DEBUG ((DEBUG_ERROR, "%a: get resource from: %s failed\n", __func__, > Uri)); > + return Status; > + } > + > + // > + // Check and see if "@Redfish.Settings" exist or not. > + // > + PendingSettingUri =3D NULL; > + Status =3D GetPendingSettings ( > + Private->RedfishService, > + Response.Payload, > + &PendingSettingResponse, > + &PendingSettingUri > + ); > + if (!EFI_ERROR (Status)) { > + DEBUG ((REDFISH_DEBUG_TRACE, "%a: @Redfish.Settings found: %s\n", > __func__, PendingSettingUri)); > + Private->Uri =3D PendingSettingUri; > + ExpectedResponse =3D &PendingSettingResponse; > + } else { > + Private->Uri =3D Uri; > + ExpectedResponse =3D &Response; > + } > + > + Private->Payload =3D ExpectedResponse->Payload; > + ASSERT (Private->Payload !=3D NULL); > + > + Private->Json =3D JsonDumpString (RedfishJsonInPayload > (Private->Payload), EDKII_JSON_COMPACT); > + ASSERT (Private->Json !=3D NULL); > + > + // > + // Searching for etag in HTTP response header > + // > + Etag =3D NULL; > + Status =3D GetHttpResponseEtag (ExpectedResponse, &Etag); > + if (EFI_ERROR (Status)) { > + DEBUG ((DEBUG_ERROR, "%a: failed to get ETag from HTTP header\n", > __func__)); > + } > + > + Status =3D RedfishConsumeResourceCommon (Private, Private->Json, Etag)= ; > + if (EFI_ERROR (Status)) { > + DEBUG ((DEBUG_ERROR, "%a: failed to consume resource from: %s: %r\n"= , > __func__, Private->Uri, Status)); > + } > + > + // > + // Release resource > + // > + RedfishHttpFreeResponse (&Response); > + RedfishHttpFreeResponse (&PendingSettingResponse); > + Private->Payload =3D NULL; > + > + if (Private->Json !=3D NULL) { > + FreePool (Private->Json); > + Private->Json =3D NULL; > + } > + > + if (Etag !=3D NULL) { > + FreePool (Etag); > + } > + > + if (PendingSettingUri !=3D NULL) { > + FreePool (PendingSettingUri); > + } > + > + return Status; > +} > + > +/** > + Get information about this protocol. > + > + @param[in] This Pointer to EFI_HP_REDFISH_HII_PROTOCO= L > instance. > + @param[out] Schema Supported schema. > + @param[out] Major Supported major number. > + @param[out] Minor Supported minor number. > + @param[out] Errata Supported errata number. > + > + @retval EFI_SUCCESS Value is returned successfully. > + @retval Others Some error happened. > + > +**/ > +EFI_STATUS > +EFIAPI > +RedfishResourceGetInfo ( > + IN EDKII_REDFISH_RESOURCE_CONFIG_PROTOCOL *This, > + OUT REDFISH_SCHEMA_INFO *Info > + ) > +{ > + if ((This =3D=3D NULL) || (Info =3D=3D NULL)) { > + return EFI_INVALID_PARAMETER; > + } > + > + AsciiStrCpyS (Info->Schema, REDFISH_SCHEMA_STRING_SIZE, > RESOURCE_SCHEMA); > + AsciiStrCpyS (Info->Major, REDFISH_SCHEMA_VERSION_SIZE, > RESOURCE_SCHEMA_MAJOR); > + AsciiStrCpyS (Info->Minor, REDFISH_SCHEMA_VERSION_SIZE, > RESOURCE_SCHEMA_MINOR); > + AsciiStrCpyS (Info->Errata, REDFISH_SCHEMA_VERSION_SIZE, > RESOURCE_SCHEMA_ERRATA); > + > + return EFI_SUCCESS; > +} > + > +/** > + Update resource to given URI. > + > + @param[in] This Pointer to EFI_HP_REDFISH_HII_PROTOCO= L > instance. > + @param[in] Uri The target URI to consume. > + > + @retval EFI_SUCCESS Value is returned successfully. > + @retval Others Some error happened. > + > +**/ > +EFI_STATUS > +EFIAPI > +RedfishResourceUpdate ( > + IN EDKII_REDFISH_RESOURCE_CONFIG_PROTOCOL *This, > + IN EFI_STRING Uri > + ) > +{ > + REDFISH_RESOURCE_COMMON_PRIVATE *Private; > + EFI_STATUS Status; > + REDFISH_RESPONSE Response; > + > + if ((This =3D=3D NULL) || IS_EMPTY_STRING (Uri)) { > + return EFI_INVALID_PARAMETER; > + } > + > + ZeroMem (&Response, sizeof (REDFISH_RESPONSE)); > + Private =3D REDFISH_RESOURCE_COMMON_PRIVATE_DATA_FROM_RESOURCE_PROTOCO= L > (This); > + > + if (Private->RedfishService =3D=3D NULL) { > + return EFI_NOT_READY; > + } > + > + Status =3D RedfishHttpGetResource (Private->RedfishService, Uri, NULL, > &Response, TRUE); > + if (EFI_ERROR (Status)) { > + DEBUG ((DEBUG_ERROR, "%a: get resource from: %s failed\n", __func__, > Uri)); > + return Status; > + } > + > + Private->Uri =3D Uri; > + Private->Payload =3D Response.Payload; > + ASSERT (Private->Payload !=3D NULL); > + > + Private->Json =3D JsonDumpString (RedfishJsonInPayload > (Private->Payload), EDKII_JSON_COMPACT); > + ASSERT (Private->Json !=3D NULL); > + > + Status =3D RedfishUpdateResourceCommon (Private, Private->Json); > + if (EFI_ERROR (Status)) { > + DEBUG ((DEBUG_ERROR, "%a: failed to update resource to: %s: %r\n", > __func__, Uri, Status)); > + } else { > + // > + // Get latest ETag on URI and keep it in variable. > + // > + SetEtagFromUri (Private->RedfishService, Private->Uri, TRUE); > + } > + > + // > + // Release resource > + // > + RedfishHttpFreeResponse (&Response); > + Private->Payload =3D NULL; > + > + if (Private->Json !=3D NULL) { > + FreePool (Private->Json); > + Private->Json =3D NULL; > + } > + > + return Status; > +} > + > +/** > + Check resource on given URI. > + > + @param[in] This Pointer to EFI_HP_REDFISH_HII_PROTOCO= L > instance. > + @param[in] Uri The target URI to consume. > + > + @retval EFI_SUCCESS Value is returned successfully. > + @retval Others Some error happened. > + > +**/ > +EFI_STATUS > +EFIAPI > +RedfishResourceCheck ( > + IN EDKII_REDFISH_RESOURCE_CONFIG_PROTOCOL *This, > + IN EFI_STRING Uri > + ) > +{ > + REDFISH_RESOURCE_COMMON_PRIVATE *Private; > + EFI_STATUS Status; > + REDFISH_RESPONSE Response; > + CHAR8 *Etag; > + > + if ((This =3D=3D NULL) || IS_EMPTY_STRING (Uri)) { > + return EFI_INVALID_PARAMETER; > + } > + > + ZeroMem (&Response, sizeof (REDFISH_RESPONSE)); > + Private =3D REDFISH_RESOURCE_COMMON_PRIVATE_DATA_FROM_RESOURCE_PROTOCO= L > (This); > + > + if (Private->RedfishService =3D=3D NULL) { > + return EFI_NOT_READY; > + } > + > + Status =3D RedfishHttpGetResource (Private->RedfishService, Uri, NULL, > &Response, TRUE); > + if (EFI_ERROR (Status)) { > + DEBUG ((DEBUG_ERROR, "%a: get resource from: %s failed\n", __func__, > Uri)); > + return Status; > + } > + > + Private->Uri =3D Uri; > + Private->Payload =3D Response.Payload; > + ASSERT (Private->Payload !=3D NULL); > + > + Private->Json =3D JsonDumpString (RedfishJsonInPayload > (Private->Payload), EDKII_JSON_COMPACT); > + ASSERT (Private->Json !=3D NULL); > + > + // > + // Find etag in HTTP response header > + // > + Etag =3D NULL; > + Status =3D GetHttpResponseEtag (&Response, &Etag); > + if (EFI_ERROR (Status)) { > + DEBUG ((DEBUG_ERROR, "%a: failed to get ETag from HTTP header\n", > __func__)); > + } > + > + Status =3D RedfishCheckResourceCommon (Private, Private->Json, Etag); > + if (EFI_ERROR (Status)) { > + DEBUG ((DEBUG_ERROR, "%a: failed to check resource from: %s: %r\n", > __func__, Uri, Status)); > + } > + > + // > + // Release resource > + // > + if (Etag !=3D NULL) { > + FreePool (Etag); > + } > + > + RedfishHttpFreeResponse (&Response); > + Private->Payload =3D NULL; > + > + if (Private->Json !=3D NULL) { > + FreePool (Private->Json); > + Private->Json =3D NULL; > + } > + > + return Status; > +} > + > +/** > + Identify resource on given URI. > + > + @param[in] This Pointer to > EDKII_REDFISH_RESOURCE_CONFIG_PROTOCOL instance. > + @param[in] Uri The target URI to consume. > + > + @retval EFI_SUCCESS This is target resource which we want > to handle. > + @retval EFI_UNSUPPORTED This is not the target resource. > + @retval Others Some error happened. > + > +**/ > +EFI_STATUS > +EFIAPI > +RedfishResourceIdentify ( > + IN EDKII_REDFISH_RESOURCE_CONFIG_PROTOCOL *This, > + IN EFI_STRING Uri > + ) > +{ > + REDFISH_RESOURCE_COMMON_PRIVATE *Private; > + EFI_STATUS Status; > + REDFISH_RESPONSE Response; > + > + if ((This =3D=3D NULL) || IS_EMPTY_STRING (Uri)) { > + return EFI_INVALID_PARAMETER; > + } > + > + ZeroMem (&Response, sizeof (REDFISH_RESPONSE)); > + Private =3D REDFISH_RESOURCE_COMMON_PRIVATE_DATA_FROM_RESOURCE_PROTOCO= L > (This); > + > + if (Private->RedfishService =3D=3D NULL) { > + return EFI_NOT_READY; > + } > + > + Status =3D RedfishHttpGetResource (Private->RedfishService, Uri, NULL, > &Response, TRUE); > + if (EFI_ERROR (Status)) { > + DEBUG ((DEBUG_ERROR, "%a: get resource from: %s failed\n", __func__, > Uri)); > + return Status; > + } > + > + Private->Uri =3D Uri; > + Private->Payload =3D Response.Payload; > + ASSERT (Private->Payload !=3D NULL); > + > + Private->Json =3D JsonDumpString (RedfishJsonInPayload > (Private->Payload), EDKII_JSON_COMPACT); > + ASSERT (Private->Json !=3D NULL); > + > + Status =3D RedfishIdentifyResourceCommon (Private, Private->Json); > + if (EFI_ERROR (Status)) { > + DEBUG ((DEBUG_ERROR, "%a: identify %s failed: %r\n", __func__, Uri, > Status)); > + } > + > + // > + // Release resource > + // > + RedfishHttpFreeResponse (&Response); > + Private->Payload =3D NULL; > + > + if (Private->Json !=3D NULL) { > + FreePool (Private->Json); > + Private->Json =3D NULL; > + } > + > + return Status; > +} > + > +EDKII_REDFISH_RESOURCE_CONFIG_PROTOCOL mRedfishResourceConfig =3D { > + RedfishResourceProvisioningResource, > + RedfishResourceConsumeResource, > + RedfishResourceUpdate, > + RedfishResourceCheck, > + RedfishResourceIdentify, > + RedfishResourceGetInfo > +}; > + > +/** > + Initialize a Redfish configure handler. > + > + This function will be called by the Redfish config driver to initializ= e > each Redfish configure > + handler. > + > + @param[in] This Pointer to > EDKII_REDFISH_CONFIG_HANDLER_PROTOCOL instance. > + @param[in] RedfishConfigServiceInfo Redfish service information. > + > + @retval EFI_SUCCESS The handler has been initialized > successfully. > + @retval EFI_DEVICE_ERROR Failed to create or configure the > REST EX protocol instance. > + @retval EFI_ALREADY_STARTED This handler has already been > initialized. > + @retval Other Error happens during the > initialization. > + > +**/ > +EFI_STATUS > +EFIAPI > +RedfishResourceInit ( > + IN EDKII_REDFISH_CONFIG_HANDLER_PROTOCOL *This, > + IN REDFISH_CONFIG_SERVICE_INFORMATION *RedfishConfigServiceInfo > + ) > +{ > + REDFISH_RESOURCE_COMMON_PRIVATE *Private; > + > + Private =3D REDFISH_RESOURCE_COMMON_PRIVATE_DATA_FROM_CONFIG_PROTOCOL > (This); > + > + Private->RedfishService =3D RedfishCreateService > (RedfishConfigServiceInfo); > + if (Private->RedfishService =3D=3D NULL) { > + return EFI_DEVICE_ERROR; > + } > + > + return EFI_SUCCESS; > +} > + > +/** > + Stop a Redfish configure handler. > + > + @param[in] This Pointer to > EDKII_REDFISH_CONFIG_HANDLER_PROTOCOL instance. > + > + @retval EFI_SUCCESS This handler has been stoped > successfully. > + @retval Others Some error happened. > + > +**/ > +EFI_STATUS > +EFIAPI > +RedfishResourceStop ( > + IN EDKII_REDFISH_CONFIG_HANDLER_PROTOCOL *This > + ) > +{ > + REDFISH_RESOURCE_COMMON_PRIVATE *Private; > + > + Private =3D REDFISH_RESOURCE_COMMON_PRIVATE_DATA_FROM_CONFIG_PROTOCOL > (This); > + > + if (Private->Event !=3D NULL) { > + gBS->CloseEvent (Private->Event); > + Private->Event =3D NULL; > + } > + > + if (Private->RedfishService !=3D NULL) { > + RedfishCleanupService (Private->RedfishService); > + Private->RedfishService =3D NULL; > + } > + > + return EFI_SUCCESS; > +} > + > +EDKII_REDFISH_CONFIG_HANDLER_PROTOCOL mRedfishConfigHandler =3D { > + RedfishResourceInit, > + RedfishResourceStop > +}; > + > +/** > + Callback function when gEfiRestJsonStructureProtocolGuid is installed. > + > + @param[in] Event Event whose notification function is being invoked= . > + @param[in] Context Pointer to the notification function's context. > +**/ > +VOID > +EFIAPI > +EfiRestJsonStructureProtocolIsReady ( > + IN EFI_EVENT Event, > + IN VOID *Context > + ) > +{ > + EFI_STATUS Status; > + > + if (mRedfishResourcePrivate =3D=3D NULL) { > + return; > + } > + > + if (mRedfishResourcePrivate->JsonStructProtocol !=3D NULL) { > + return; > + } > + > + Status =3D gBS->LocateProtocol ( > + &gEfiRestJsonStructureProtocolGuid, > + NULL, > + (VOID **)&mRedfishResourcePrivate->JsonStructProtocol > + ); > + if (EFI_ERROR (Status)) { > + DEBUG ((DEBUG_ERROR, "%a: failed to locate > gEfiRestJsonStructureProtocolGuid: %r\n", __func__, Status)); > + } > + > + gBS->CloseEvent (Event); > +} > + > +/** > + Unloads an image. > + > + @param ImageHandle Handle that identifies the image to be > unloaded. > + > + @retval EFI_SUCCESS The image has been unloaded. > + @retval EFI_INVALID_PARAMETER ImageHandle is not a valid image handle. > + > +**/ > +EFI_STATUS > +EFIAPI > +RedfishResourceUnload ( > + IN EFI_HANDLE ImageHandle > + ) > +{ > + EFI_STATUS Status; > + EDKII_REDFISH_CONFIG_HANDLER_PROTOCOL *ConfigHandler; > + > + if (mRedfishResourcePrivate =3D=3D NULL) { > + return EFI_NOT_READY; > + } > + > + ConfigHandler =3D NULL; > + > + // > + // Firstly, find ConfigHandler Protocol interface in this ImageHandle. > + // > + Status =3D gBS->OpenProtocol ( > + ImageHandle, > + &gEdkIIRedfishConfigHandlerProtocolGuid, > + (VOID **)&ConfigHandler, > + NULL, > + NULL, > + EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL > + ); > + if (EFI_ERROR (Status) || (ConfigHandler =3D=3D NULL)) { > + return Status; > + } > + > + ConfigHandler->Stop (ConfigHandler); > + > + // > + // Last, uninstall ConfigHandler Protocol and resource protocol. > + // > + Status =3D gBS->UninstallMultipleProtocolInterfaces ( > + ImageHandle, > + &gEdkIIRedfishConfigHandlerProtocolGuid, > + ConfigHandler, > + &gEdkIIRedfishResourceConfigProtocolGuid, > + &mRedfishResourcePrivate->RedfishResourceConfig, > + NULL > + ); > + > + FreePool (mRedfishResourcePrivate); > + mRedfishResourcePrivate =3D NULL; > + > + return Status; > +} > + > +/** > + The callback function provided by Redfish Feature driver. > + > + @param[in] This Pointer to > EDKII_REDFISH_FEATURE_PROTOCOL instance. > + @param[in] FeatureAction The action Redfish feature driver > should take. > + @param[in] Uri The collection URI. > + @param[in] Context The context of Redfish feature > driver. > + @param[in,out] InformationExchange The pointer to > RESOURCE_INFORMATION_EXCHANGE > + > + @retval EFI_SUCCESS Redfish feature driver callback is > executed successfully. > + @retval Others Some errors happened. > + > + @retval EFI_SUCCESS Redfish feature driver callback is > executed successfully. > + @retval Others Some errors happened. > + > +**/ > +EFI_STATUS > +EFIAPI > +RedfishExternalResourceResourceFeatureCallback ( > + IN EDKII_REDFISH_FEATURE_PROTOCOL *This, > + IN FEATURE_CALLBACK_ACTION FeatureAction, > + IN VOID *Context, > + IN OUT RESOURCE_INFORMATION_EXCHANGE *InformationExchange > + ) > +{ > + EFI_STATUS Status; > + REDFISH_SERVICE RedfishService; > + REDFISH_RESOURCE_COMMON_PRIVATE *Private; > + EFI_STRING ResourceUri; > + EFI_STRING SecureBootUri; > + > + if (FeatureAction !=3D CallbackActionStartOperation) { > + return EFI_UNSUPPORTED; > + } > + > + Private =3D (REDFISH_RESOURCE_COMMON_PRIVATE *)Context; > + > + RedfishService =3D Private->RedfishService; > + if (RedfishService =3D=3D NULL) { > + DEBUG ((DEBUG_ERROR, "%a: no Redfish service configured\n", > __func__)); > + return EFI_NOT_READY; > + } > + > + // > + // Save in private structure. > + // > + Private->InformationExchange =3D InformationExchange; > + > + // > + // Find Redfish version on Redfish ser > + // > + Private->RedfishVersion =3D RedfishGetVersion (RedfishService); > + > + // > + // Create the full URI from Redfish service root. > + // > + ResourceUri =3D (EFI_STRING)AllocateZeroPool (MAX_URI_LENGTH * sizeof > (CHAR16)); > + if (ResourceUri =3D=3D NULL) { > + DEBUG ((DEBUG_ERROR, "%a: Fail to allocate memory for full URI.\n", > __func__)); > + return EFI_OUT_OF_RESOURCES; > + } > + > + StrCatS (ResourceUri, MAX_URI_LENGTH, Private->RedfishVersion); > + StrCatS (ResourceUri, MAX_URI_LENGTH, > InformationExchange->SendInformation.FullUri); > + > + // > + // Initialize collection path > + // > + SecureBootUri =3D RedfishGetUri (ResourceUri); > + if (SecureBootUri =3D=3D NULL) { > + ASSERT (FALSE); > + FreePool (ResourceUri); > + return EFI_OUT_OF_RESOURCES; > + } > + > + Status =3D HandleResource (Private, SecureBootUri); > + if (EFI_ERROR (Status)) { > + DEBUG ((DEBUG_ERROR, "%a: process external resource: %s failed: > %r\n", __func__, SecureBootUri, Status)); > + } > + > + FreePool (SecureBootUri); > + FreePool (ResourceUri); > + return Status; > +} > + > +/** > + Callback function when gEdkIIRedfishFeatureProtocolGuid is installed. > + > + @param[in] Event Event whose notification function is being invoked= . > + @param[in] Context Pointer to the notification function's context. > +**/ > +VOID > +EFIAPI > +EdkIIRedfishFeatureProtocolIsReady ( > + IN EFI_EVENT Event, > + IN VOID *Context > + ) > +{ > + EFI_STATUS Status; > + EDKII_REDFISH_FEATURE_PROTOCOL *FeatureProtocol; > + > + if (mRedfishResourcePrivate =3D=3D NULL) { > + return; > + } > + > + if (mRedfishResourcePrivate->FeatureProtocol !=3D NULL) { > + return; > + } > + > + Status =3D gBS->LocateProtocol ( > + &gEdkIIRedfishFeatureProtocolGuid, > + NULL, > + (VOID **)&FeatureProtocol > + ); > + if (EFI_ERROR (Status)) { > + DEBUG ((DEBUG_ERROR, "%a: failed to locate > gEdkIIRedfishFeatureProtocolGuid: %r\n", __func__, Status)); > + gBS->CloseEvent (Event); > + return; > + } > + > + Status =3D FeatureProtocol->Register ( > + FeatureProtocol, > + REDFISH_MANAGED_URI, > + > RedfishExternalResourceResourceFeatureCallba= ck, > + (VOID *)mRedfishResourcePrivate > + ); > + if (EFI_ERROR (Status)) { > + DEBUG ((DEBUG_ERROR, "%a: failed to register %s: %r\n", __func__, > REDFISH_MANAGED_URI, Status)); > + } > + > + mRedfishResourcePrivate->FeatureProtocol =3D FeatureProtocol; > + > + gBS->CloseEvent (Event); > +} > + > +/** > + This is the declaration of an EFI image entry point. This entry point = is > + the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers > including > + both device drivers and bus drivers. It initialize the global variable= s > and > + publish the driver binding protocol. > + > + @param[in] ImageHandle The firmware allocated handle for the > UEFI image. > + @param[in] SystemTable A pointer to the EFI System Table. > + > + @retval EFI_SUCCESS The operation completed successfully. > + @retval EFI_ACCESS_DENIED EFI_ISCSI_INITIATOR_NAME_PROTOCOL was > installed unexpectedly. > + @retval Others Other errors as indicated. > +**/ > +EFI_STATUS > +EFIAPI > +RedfishResourceEntryPoint ( > + IN EFI_HANDLE ImageHandle, > + IN EFI_SYSTEM_TABLE *SystemTable > + ) > +{ > + EFI_STATUS Status; > + VOID *Registration; > + > + if (mRedfishResourcePrivate !=3D NULL) { > + return EFI_ALREADY_STARTED; > + } > + > + mRedfishResourceConfigProtocolHandle =3D ImageHandle; > + > + mRedfishResourcePrivate =3D AllocateZeroPool (sizeof > (REDFISH_RESOURCE_COMMON_PRIVATE)); > + CopyMem (&mRedfishResourcePrivate->ConfigHandler, > &mRedfishConfigHandler, sizeof (EDKII_REDFISH_CONFIG_HANDLER_PROTOCOL)); > + CopyMem (&mRedfishResourcePrivate->RedfishResourceConfig, > &mRedfishResourceConfig, sizeof (EDKII_REDFISH_RESOURCE_CONFIG_PROTOCOL))= ; > + > + // > + // Publish config handler protocol and resource protocol. > + // > + Status =3D gBS->InstallMultipleProtocolInterfaces ( > + &ImageHandle, > + &gEdkIIRedfishConfigHandlerProtocolGuid, > + &mRedfishResourcePrivate->ConfigHandler, > + &gEdkIIRedfishResourceConfigProtocolGuid, > + &mRedfishResourcePrivate->RedfishResourceConfig, > + NULL > + ); > + > + EfiCreateProtocolNotifyEvent ( > + &gEfiRestJsonStructureProtocolGuid, > + TPL_CALLBACK, > + EfiRestJsonStructureProtocolIsReady, > + NULL, > + &Registration > + ); > + > + EfiCreateProtocolNotifyEvent ( > + &gEdkIIRedfishFeatureProtocolGuid, > + TPL_CALLBACK, > + EdkIIRedfishFeatureProtocolIsReady, > + (VOID *)mRedfishResourcePrivate, > + &Registration > + ); > + > + return Status; > +} > diff --git a/RedfishClientPkg/RedfishClient.fdf.inc > b/RedfishClientPkg/RedfishClient.fdf.inc > index 59b8acba1..154f641b2 100644 > --- a/RedfishClientPkg/RedfishClient.fdf.inc > +++ b/RedfishClientPkg/RedfishClient.fdf.inc > @@ -25,6 +25,7 @@ > INF RedfishClientPkg/HiiToRedfishBiosDxe/HiiToRedfishBiosDxe.inf > INF > RedfishClientPkg/Features/BootOptionCollection/BootOptionCollectionDxe.in= f > INF RedfishClientPkg/Features/BootOption/v1_0_4/Dxe/BootOptionDxe.inf > + INF RedfishClientPkg/Features/SecureBoot/v1_1_0/Dxe/SecureBootDxe.inf > > !include RedfishClientPkg/RedfishJsonStructureDxe.fdf.inc > # > -- > 2.34.1 > > > > > > > > Regards, > > Mike > > > Regards, Mike. -=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 (#117142): https://edk2.groups.io/g/devel/message/117142 Mute This Topic: https://groups.io/mt/104927848/7686176 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- --000000000000c65f1206149836c7 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
Hi Nickle,

On Tue, Mar= 26, 2024 at 4:57=E2=80=AFPM Nickle Wang <nicklew@nvidia.com> wrote:

Hi Mike,

=C2=A0

Thanks for your review. I addressed your review comm= ents in pull request: https://github.com/tianocore/edk2-redfish-client/pull/83

=C2=A0

I am waiting for Abner=E2=80=99s patch (PR#84) becau= se I plan to incorporate Abner=E2=80=99s changes into this driver. I will s= end version 2 patch series here for review later.

=C2=A0

Regards,

Nickle

=C2=A0



I see my comments were addressed, and I agree with that.

But I think I found another minor leaks in a common pattern= :
+ = =C2=A0if (PropertyChecker (SecureBootCs->SecureBootMode, ProvisionMode))= {
+ =C2=A0=C2=A0=C2=A0Status =3D GetSetupMode (&SetupMode);
+ = =C2=A0=C2=A0=C2=A0if (!EFI_ERROR (Status)) {
+ =C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0AsciiStringValue =3D AllocateZeroPool (SECURE_BOOT_MODE_STR_LEN *size= of (CHAR8));
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0if (AsciiStringValue !=3D N= ULL) {
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0AsciiSPrint (AsciiStr= ingValue, SECURE_BOOT_MODE_STR_LEN *sizeof (CHAR8), "%a", (SetupM= ode =3D=3D USER_MODE ? SECURE_BOOT_USER_MODE : SECURE_BOOT_SETUP_MODE));+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0if (ProvisionMode || (AsciiStr= Cmp (SecureBootCs->SecureBootMode, AsciiStringValue) !=3D 0)) {
+ =C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0SecureBootCs->SecureB= ootMode =3D AsciiStringValue;
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0PropertyChanged =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=3D TRUE;
+ =C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0}
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0}
+ =C2=A0=C2=A0= =C2=A0} else {
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0DEBUG ((DEBUG_ERROR, &quo= t;%a: cannot read setup mode: %r\n", __func__, Status));
+ =C2=A0= =C2=A0=C2=A0}
+ =C2=A0}
For the case when=C2=A0PropertyChanged left FAL= SE, allocated values=C2=A0AsciiStringValue and=C2=A0IntegerValue are leaked.

=
Also there is a one new question below:
= =C2=A0

From: Mike Maslenkin <mike.maslenkin@gmail.com> =
Sent: Friday, March 15, 2024 3:38 AM
To: devel@= edk2.groups.io; Nickle Wang <nicklew@nvidia.com>
Cc: Abner Chang <abner.chang@amd.com>; Igor Kulchytskyy <igork@ami.com>; Nick Ramirez <= nramirez@nvidia.co= m>
Subject: Re: [edk2-devel] [edk2-redfish-client][PATCH 1/2] RedfishCl= ientPkg/Features: support Redfish Secure Boot

=C2=A0

External email: Use caution opening links or atta= chments

=C2=A0

Hi Nickle,

=C2=A0

please find my comments below



On 14. 3. 2024., at 17:53, Nickle Wang via groups.io <nicklew=3Dnvidia.com@groups.io> wrote:

=C2=A0

Introduce SecureBoot driver to support
/redfish/v1/Systems/SYS/SecureBoot resource.

Signed-off-by: Nickle Wang <nicklew@nvidia.com>
Cc: Abner Chang <abner.chang@amd.com>
Cc: Igor Kulchytskyy <igork@ami.com>
Cc: Nick Ramirez <nramirez@nvidia.com>
---
.../RedfishClientComponents.dsc.inc =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0| =C2=A0=C2=A02 +
RedfishClientPkg/RedfishClientLibs.dsc.inc =C2=A0=C2=A0=C2=A0| =C2=A0=C2=A0= 4 +
.../SecureBoot/v1_1_0/Dxe/SecureBootDxe.inf =C2=A0=C2=A0| =C2=A060 ++
.../v1_1_0/Common/SecureBootCommon.h =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0| =C2=A040 +
.../v1_1_0/Common/SecureBootCommon.c =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0| 756 ++++++++++++++++
.../SecureBoot/v1_1_0/Dxe/SecureBootDxe.c =C2=A0=C2=A0=C2=A0=C2=A0| 808 +++= +++++++++++++++
RedfishClientPkg/RedfishClient.fdf.inc =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0| =C2=A0=C2=A01 +
7 files changed, 1671 insertions(+)
create mode 100644 RedfishClientPkg/Features/SecureBoot/v1_1_0/Dxe/SecureBo= otDxe.inf
create mode 100644 RedfishClientPkg/Features/SecureBoot/v1_1_0/Common/Secur= eBootCommon.h
create mode 100644 RedfishClientPkg/Features/SecureBoot/v1_1_0/Common/Secur= eBootCommon.c
create mode 100644 RedfishClientPkg/Features/SecureBoot/v1_1_0/Dxe/SecureBo= otDxe.c

diff --git a/RedfishClientPkg/RedfishClientComponents.dsc.inc b/RedfishClie= ntPkg/RedfishClientComponents.dsc.inc
index ae2a4b025..42fc0c299 100644
--- a/RedfishClientPkg/RedfishClientComponents.dsc.inc
+++ b/RedfishClientPkg/RedfishClientComponents.dsc.inc
@@ -34,6 +34,7 @@
=C2=A0=C2=A0RedfishClientPkg/Features/Bios/v1_0_9/Dxe/BiosDxe.inf
=C2=A0=C2=A0RedfishClientPkg/Features/BootOptionCollection/BootOptionCollec= tionDxe.inf
=C2=A0=C2=A0RedfishClientPkg/Features/BootOption/v1_0_4/Dxe/BootOptionDxe.i= nf
+ =C2=A0RedfishClientPkg/Features/SecureBoot/v1_1_0/Dxe/SecureBootDxe.inf
=C2=A0=C2=A0!include RedfishClientPkg/RedfishJsonStructureDxe.dsc.inc

@@ -47,3 +48,4 @@
=C2=A0=C2=A0RedfishClientPkg/Converter/Bios/v1_0_9/RedfishBios_V1_0_9_Dxe.i= nf
=C2=A0=C2=A0RedfishClientPkg/Converter/BootOptionCollection/RedfishBootOpti= onCollection_Dxe.inf
=C2=A0=C2=A0RedfishClientPkg/Converter/BootOption/v1_0_4/RedfishBootOption_= V1_0_4_Dxe.inf
+ =C2=A0RedfishClientPkg/Converter/SecureBoot/v1_1_0/RedfishSecureBoot_V1_1= _0_Dxe.inf
diff --git a/RedfishClientPkg/RedfishClientLibs.dsc.inc b/RedfishClientPkg/= RedfishClientLibs.dsc.inc
index 6599926ab..9126465df 100644
--- a/RedfishClientPkg/RedfishClientLibs.dsc.inc
+++ b/RedfishClientPkg/RedfishClientLibs.dsc.inc
@@ -25,6 +25,8 @@
=C2=A0=C2=A0BiosV1_0_9Lib|RedfishClientPkg/ConverterLib/edk2library/Bios/v1= _0_9/Lib.inf
=C2=A0=C2=A0BootOptionCollectionLib|RedfishClientPkg/ConverterLib/edk2libra= ry/BootOptionCollection/Lib.inf
=C2=A0=C2=A0BootOptionV1_0_4Lib|RedfishClientPkg/ConverterLib/edk2library/B= ootOption/v1_0_4/Lib.inf
+ =C2=A0SecureBootV1_1_0Lib|RedfishClientPkg/ConverterLib/edk2library/Secur= eBoot/v1_1_0/Lib.inf
+
=C2=A0=C2=A0#
=C2=A0=C2=A0# Above modules should be pulled in by build tool.
=C2=A0=C2=A0#
@@ -42,3 +44,5 @@
=C2=A0=C2=A0RedfishAddendumLib|RedfishClientPkg/Library/RedfishAddendumLib/= RedfishAddendumLib.inf
=C2=A0=C2=A0RedfishDebugLib|RedfishPkg/Library/RedfishDebugLib/RedfishDebug= Lib.inf
=C2=A0=C2=A0RedfishHttpLib|RedfishPkg/Library/RedfishHttpLib/RedfishHttpLib= .inf
+ =C2=A0SecureBootVariableLib|SecurityPkg/Library/SecureBootVariableLib/Sec= ureBootVariableLib.inf
+ =C2=A0PlatformPKProtectionLib|SecurityPkg/Library/PlatformPKProtectionLib= VarPolicy/PlatformPKProtectionLibVarPolicy.inf
diff --git a/RedfishClientPkg/Features/SecureBoot/v1_1_0/Dxe/SecureBootDxe.= inf b/RedfishClientPkg/Features/SecureBoot/v1_1_0/Dxe/SecureBootDxe.inf
new file mode 100644
index 000000000..1ad8c623f
--- /dev/null
+++ b/RedfishClientPkg/Features/SecureBoot/v1_1_0/Dxe/SecureBootDxe.inf
@@ -0,0 +1,60 @@
+## @file
+#
+# =C2=A0(C) Copyright 2020-2022 Hewlett Packard Enterprise Development LP&= lt;BR>
+# =C2=A0Copyright (c) 2022-2024, NVIDIA CORPORATION & AFFILIATES. All = rights reserved.
+#
+# =C2=A0SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+
+[Defines]
+ =C2=A0INF_VERSION =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=3D 0x00010005
+ =C2=A0BASE_NAME =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=3D SecureBootDxe
+ =C2=A0FILE_GUID =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=3D 5E4025F8-DA42-468A-853E-6A1091D3= 5052
+ =C2=A0MODULE_TYPE =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=3D DXE_DRIVER
+ =C2=A0VERSION_STRING =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=3D 1.0
+ =C2=A0ENTRY_POINT =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=3D RedfishResourceEntryPoint
+ =C2=A0UNLOAD_IMAGE =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=3D RedfishResourceUnload
+
+[Packages]
+ =C2=A0MdePkg/MdePkg.dec
+ =C2=A0MdeModulePkg/MdeModulePkg.dec
+ =C2=A0SecurityPkg/SecurityPkg.dec
+ =C2=A0RedfishPkg/RedfishPkg.dec
+ =C2=A0RedfishClientPkg/RedfishClientPkg.dec
+
+[Sources]
+ =C2=A0../Common/SecureBootCommon.h
+ =C2=A0../Common/SecureBootCommon.c
+ =C2=A0SecureBootDxe.c
+
+[LibraryClasses]
+ =C2=A0BaseMemoryLib
+ =C2=A0DebugLib
+ =C2=A0EdkIIRedfishResourceConfigLib
+ =C2=A0RedfishFeatureUtilityLib
+ =C2=A0RedfishVersionLib
+ =C2=A0RedfishResourceIdentifyLib
+ =C2=A0SecureBootVariableLib
+ =C2=A0UefiLib
+ =C2=A0UefiDriverEntryPoint
+ =C2=A0RedfishAddendumLib

+ =C2=A0U= efiRuntimeServicesTableLib
+
+[Protocols]
+ =C2=A0gEdkIIRedfishConfigHandlerProtocolGuid =C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0## PRODUCED
+ =C2=A0gEfiRestJsonStructureProtocolGuid =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0## CONSUMED
+ =C2=A0gEdkIIRedfishResourceConfigProtocolGuid =C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0## PRODUCED
+ =C2=A0gEdkIIRedfishFeatureProtocolGuid =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0## CONSUMED
+
+[Guids]
+ =C2=A0gEfiSecureBootEnableDisableGuid =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0## CONSUMED<= br> +
+[Pcd]
+ =C2=A0gEfiRedfishClientPkgTokenSpaceGuid.PcdMaxRedfishSchemaStringSize + =C2=A0gEfiRedfishClientPkgTokenSpaceGuid.PcdMaxRedfishSchemaVersionSize + =C2=A0gEfiRedfishClientPkgTokenSpaceGuid.PcdRedfishSystemRebootRequired +
+[Depex]
+ =C2=A0TRUE
diff --git a/RedfishClientPkg/Features/SecureBoot/v1_1_0/Common/SecureBootC= ommon.h b/RedfishClientPkg/Features/SecureBoot/v1_1_0/Common/SecureBootComm= on.h
new file mode 100644
index 000000000..0d1824160
--- /dev/null
+++ b/RedfishClientPkg/Features/SecureBoot/v1_1_0/Common/SecureBootCommon.h=
@@ -0,0 +1,40 @@
+/** @file
+
+ =C2=A0Redfish feature driver implementation - internal header file
+ =C2=A0(C) Copyright 2020-2022 Hewlett Packard Enterprise Development LP&l= t;BR>
+ =C2=A0Copyright (c) 2022-2024, NVIDIA CORPORATION & AFFILIATES. All r= ights reserved.
+
+ =C2=A0SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef EFI_REDFISH_SECUREBOOT_COMMON_H_
+#define EFI_REDFISH_SECUREBOOT_COMMON_H_
+
+#include <Guid/ImageAuthentication.h>
+#include <Guid/GlobalVariable.h>
+#include <Guid/AuthenticatedVariableFormat.h>
+#include <RedfishJsonStructure/SecureBoot/v1_1_0/EfiSecureBootV1_1_0.h&= gt;
+#include <RedfishResourceCommon.h>
+#include <UefiSecureBoot.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/SecureBootVariableLib.h>
+
+//
+// Schema information.
+//
+#define REDFISH_MANAGED_URI =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0L&qu= ot;Systems/{}/SecureBoot"
+#define REDFISH_DUMMY_CONFIG_LANG =C2=A0L"Systems/{1}/SecureBoot"= ;
+#define MAX_URI_LENGTH =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0256
+#define RESOURCE_SCHEMA =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0"SecureBoot"
+#define RESOURCE_SCHEMA_MAJOR =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0"1"<= br> +#define RESOURCE_SCHEMA_MINOR =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0"1"<= br> +#define RESOURCE_SCHEMA_ERRATA =C2=A0=C2=A0=C2=A0=C2=A0"0"
+#define RESOURCE_SCHEMA_VERSION =C2=A0=C2=A0=C2=A0"v1_1_0"
+#define SECURE_BOOT_SETUP_MODE =C2=A0=C2=A0=C2=A0=C2=A0"SetupMode&quo= t;
+#define SECURE_BOOT_USER_MODE =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0"UserMode= "
+#define SECURE_BOOT_ENABLED =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0&quo= t;Enabled"
+#define SECURE_BOOT_DISABLED =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0"Dis= abled"
+#define SECURE_BOOT_MODE_STR_LEN =C2=A0=C2=A016
+
+#endif
diff --git a/RedfishClientPkg/Features/SecureBoot/v1_1_0/Common/SecureBootC= ommon.c b/RedfishClientPkg/Features/SecureBoot/v1_1_0/Common/SecureBootComm= on.c
new file mode 100644
index 000000000..56a45ee72
--- /dev/null
+++ b/RedfishClientPkg/Features/SecureBoot/v1_1_0/Common/SecureBootCommon.c=
@@ -0,0 +1,756 @@
+/** @file
+ =C2=A0Redfish feature driver implementation - common functions
+
+ =C2=A0(C) Copyright 2020-2022 Hewlett Packard Enterprise Development LP&l= t;BR>
+ =C2=A0Copyright (c) 2023-2024, NVIDIA CORPORATION & AFFILIATES. All r= ights reserved.
+
+ =C2=A0SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "SecureBootCommon.h"
+
+CHAR8 =C2=A0SecureBootEmptyJson[] =3D "{\"@odata.id\": \"\", \"@odat= a.type\": \"#SecureBoot.v1_1_0.SecureBoot\", \"Id\"= ;: \"\", \"Name\": \"\", \"Attributes\&q= uot;:{}}";
+
+REDFISH_RESOURCE_COMMON_PRIVATE =C2=A0*mRedfishResourcePrivate =C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=3D NULL;
+EFI_HANDLE =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0mRedfi= shResourceConfigProtocolHandle =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=3D NULL;
+CHAR16 =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0*mSecureBootSupportedAttributes[SECURE_BOOT_MODE_STR_LEN] = =3D {
+ =C2=A0L"SecureBootCurrentBoot",
+ =C2=A0L"SecureBootEnable",
+ =C2=A0L"SecureBootMode"
+};
+
+/**
+ =C2=A0Read EFI_SECURE_BOOT_ENABLE_NAME variable and return its value to c= aller.
+
+ =C2=A0@retval BOOLEAN =C2=A0=C2=A0=C2=A0TRUE when EFI_SECURE_BOOT_ENABLE_= NAME value is SECURE_BOOT_ENABLE
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0FALSE when EFI_SECURE_BOOT_= ENABLE_NAME value is SECURE_BOOT_DISABLE
+**/
+BOOLEAN
+RedfishReadSecureBootEnable (
+ =C2=A0VOID
+ =C2=A0)
+{
+ =C2=A0UINT8 =C2=A0=C2=A0=C2=A0*Buffer;
+ =C2=A0BOOLEAN =C2=A0SecureBootEnableValue;
+
+ =C2=A0Buffer =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=3D NULL;
+ =C2=A0SecureBootEnableValue =3D FALSE;
+
+ =C2=A0GetVariable2 (
+ =C2=A0=C2=A0=C2=A0EFI_SECURE_BOOT_ENABLE_NAME,
+ =C2=A0=C2=A0=C2=A0&gEfiSecureBootEnableDisableGuid,
+ =C2=A0=C2=A0=C2=A0(VOID **)&Buffer,
+ =C2=A0=C2=A0=C2=A0NULL
+ =C2=A0=C2=A0=C2=A0);
+
+ =C2=A0if (Buffer !=3D NULL) {
+ =C2=A0=C2=A0=C2=A0if (*Buffer =3D=3D SECURE_BOOT_ENABLE) {
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0SecureBootEnableValue =3D TRUE;
+ =C2=A0=C2=A0=C2=A0}
+
+ =C2=A0=C2=A0=C2=A0FreePool (Buffer);
+ =C2=A0}
+
+ =C2=A0return SecureBootEnableValue;
+}
+
+/**
+ =C2=A0Write EFI_SECURE_BOOT_ENABLE_NAME variable with given value.
+
+ =C2=A0@param[in] =C2=A0=C2=A0SecureBootEnableValue =C2=A0=C2=A0=C2=A0Valu= e to write. TRUE is SECURE_BOOT_ENABLE.
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0FALSE is SECURE_BOOT_DISABLE.
+
+ =C2=A0@retval EFI_SUCCESS =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0Write value successfully.
+ =C2=A0@retval Others =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0Some error happene= d.
+**/
+EFI_STATUS
+RedfishWriteSecureBootEnable (
+ =C2=A0BOOLEAN =C2=A0SecureBootEnableValue
+ =C2=A0)
+{
+ =C2=A0EFI_STATUS =C2=A0Status;
+ =C2=A0UINT8 =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0VarValue;
+
+ =C2=A0VarValue =3D (SecureBootEnableValue ? SECURE_BOOT_ENABLE : SECURE_B= OOT_DISABLE);
+ =C2=A0Status =C2=A0=C2=A0=3D gRT->SetVariable (
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0EFI_SECURE_BOOT_ENABLE_NAME,
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0&gEfiSecureBootEnableDisableG= uid,
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0EFI_VARIABLE_NON_VOLATILE | EFI_V= ARIABLE_BOOTSERVICE_ACCESS,
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0sizeof (VarValue),
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0&VarValue
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0);
+
+ =C2=A0return Status;
+}
+
+/**
+ =C2=A0Consume Redfish resource in given Json data.
+
+ =C2=A0@param[in] =C2=A0=C2=A0This =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0Pointer to REDFISH_RESOU= RCE_COMMON_PRIVATE instance.
+ =C2=A0@param[in] =C2=A0=C2=A0Json =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0The JSON to consume.
+ =C2=A0@param[in] =C2=A0=C2=A0HeaderEtag =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0The Etag string returned in HTTP header.
+
+ =C2=A0@retval EFI_SUCCESS =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0Consume Redfish attribute successfully. + =C2=A0@retval Others =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0Some error happene= d.
+
+**/
+EFI_STATUS
+RedfishConsumeResourceCommon (
+ =C2=A0IN =C2=A0REDFISH_RESOURCE_COMMON_PRIVATE =C2=A0*Private,
+ =C2=A0IN =C2=A0CHAR8 =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0*Json,
+ =C2=A0IN =C2=A0CHAR8 =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0*HeaderEtag OPTIONAL
+ =C2=A0)
+{
+ =C2=A0EFI_STATUS =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0Status;
+ =C2=A0EFI_REDFISH_SECUREBOOT_V1_1_0 =C2=A0=C2=A0=C2=A0=C2=A0*SecureBoot;<= br> + =C2=A0EFI_REDFISH_SECUREBOOT_V1_1_0_CS =C2=A0*SecureBootCs;
+ =C2=A0BOOLEAN =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0SecureBootEnableDisable;
+
+ =C2=A0if ((Private =3D=3D NULL) || IS_EMPTY_STRING (Json)) {
+ =C2=A0=C2=A0=C2=A0return EFI_INVALID_PARAMETER;
+ =C2=A0}
+
+ =C2=A0SecureBoot =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=3D NULL;
+ =C2=A0SecureBootCs =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=3D NULL;
+ =C2=A0SecureBootEnableDisable =3D RedfishReadSecureBootEnable ();
+
+ =C2=A0Status =3D Private->JsonStructProtocol->ToStructure (
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0Private->JsonStructProtocol,
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0NULL,
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0Json,
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0(EFI_REST_JSON_STRUCTURE_HEADER **)&SecureBoot<= br> + =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0);
+ =C2=A0if (EFI_ERROR (Status)) {
+ =C2=A0=C2=A0=C2=A0DEBUG ((DEBUG_ERROR, "%a: ToStructure() failed: %r= \n", __func__, Status));
+ =C2=A0=C2=A0=C2=A0return Status;
+ =C2=A0}
+
+ =C2=A0SecureBootCs =3D SecureBoot->SecureBoot;
+
+ =C2=A0//
+ =C2=A0// Check ETAG to see if we need to consume it
+ =C2=A0//
+ =C2=A0if (CheckEtag (Private->Uri, HeaderEtag, SecureBootCs->odata_= etag)) {
+ =C2=A0=C2=A0=C2=A0//
+ =C2=A0=C2=A0=C2=A0// No change
+ =C2=A0=C2=A0=C2=A0//
+ =C2=A0=C2=A0=C2=A0DEBUG ((REDFISH_DEBUG_TRACE, "%a: ETAG: %s has no = change, ignore consume action\n", __func__, Private->Uri));
+ =C2=A0=C2=A0=C2=A0Status =3D EFI_ALREADY_STARTED;
+ =C2=A0=C2=A0=C2=A0goto ON_RELEASE;
+ =C2=A0}
+
+ =C2=A0//
+ =C2=A0// Secure boot enable
+ =C2=A0//
+ =C2=A0if (SecureBootCs->SecureBootEnable !=3D NULL) {
+ =C2=A0=C2=A0=C2=A0if (SecureBootEnableDisable !=3D *SecureBootCs->Secu= reBootEnable) {
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0//
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0// Write value to "SecureBootEnable&qu= ot; variable. AuthVariableLib will enable or disable secure boot
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0// based on "SecureBootEnable" va= lue.
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0//
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0Status =3D RedfishWriteSecureBootEnable (*S= ecureBootCs->SecureBootEnable);
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0if (EFI_ERROR (Status)) {
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0DEBUG ((DEBUG_ERROR, "%a: = write secure boot enable disable failed: %r\n", __func__, Status)); + =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0} else {
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0REDFISH_ENABLE_SYSTEM_REBOOT ()= ;
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0}
+ =C2=A0=C2=A0=C2=A0} else {
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0DEBUG ((REDFISH_DEBUG_TRACE, "%a: secu= re boot mode is not changed\n", __func__));
+ =C2=A0=C2=A0=C2=A0}
+ =C2=A0}
+
+ON_RELEASE:
+
+ =C2=A0//
+ =C2=A0// Release resource.
+ =C2=A0//
+ =C2=A0Private->JsonStructProtocol->DestoryStructure (
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0Private->JsonStructProtocol= ,
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0(EFI_REST_JSON_STRUCTURE_HEADE= R *)SecureBoot
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0);
+
+ =C2=A0return EFI_SUCCESS;
+}
+
+/**
+ =C2=A0Provision Redfish resource. This function reads secure boot variabl= e and convert it
+ =C2=A0to Redfish attribute.
+
+ =C2=A0@param[in] =C2=A0=C2=A0JsonStructProtocol =C2=A0Pointer to Json str= ucture protocol.
+ =C2=A0@param[in] =C2=A0=C2=A0InputJson =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0Jason data on input.
+ =C2=A0@param[in] =C2=A0=C2=A0ResourceId =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0Resource ID. This is optional.
+ =C2=A0@param[in] =C2=A0=C2=A0ConfigureLang =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0Configure language for this Redfish resource.
+ =C2=A0@param[in] =C2=A0=C2=A0ProvisionMode =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0TRUE when this is to provision Redfish attribute to
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0Redfish service. F= ALSE is to update Redfish attribute
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0to Redfish service= .
+ =C2=A0@param[out] =C2=A0ResultJson =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0Json data on output.
+
+ =C2=A0@retval EFI_SUCCESS =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0Provision Redfish attribute successfully.<= br> + =C2=A0@retval Others =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0Some error happene= d.
+
+**/
+EFI_STATUS
+ProvisioningSecureBootProperties (
+ =C2=A0IN =C2=A0EFI_REST_JSON_STRUCTURE_PROTOCOL =C2=A0*JsonStructProtocol= ,
+ =C2=A0IN =C2=A0CHAR8 =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0*InputJson,
+ =C2=A0IN =C2=A0CHAR8 =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0*ResourceId OPTIONAL,
+ =C2=A0IN =C2=A0EFI_STRING =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0ConfigureLang,
+ =C2=A0IN =C2=A0BOOLEAN =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0ProvisionMode,
+ =C2=A0OUT CHAR8 =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0**ResultJson
+ =C2=A0)
+{
+ =C2=A0EFI_REDFISH_SECUREBOOT_V1_1_0 =C2=A0=C2=A0=C2=A0=C2=A0*SecureBoot;<= br> + =C2=A0EFI_REDFISH_SECUREBOOT_V1_1_0_CS =C2=A0*SecureBootCs;
+ =C2=A0EFI_STATUS =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0Status;
+ =C2=A0BOOLEAN =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0PropertyChanged;
+ =C2=A0CHAR8 =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0*AsciiStringValue;
+ =C2=A0INT32 =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0*IntegerValue;
+ =C2=A0UINT8 =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0SetupMode;
+ =C2=A0BOOLEAN =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0SecureBootEnabled;
+ =C2=A0BOOLEAN =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0SecureBootEnableDisable;
+
+ =C2=A0if ((JsonStructProtocol =3D=3D NULL) || (ResultJson =3D=3D NULL) ||= IS_EMPTY_STRING (InputJson) || IS_EMPTY_STRING (ConfigureLang)) {
+ =C2=A0=C2=A0=C2=A0return EFI_INVALID_PARAMETER;
+ =C2=A0}
+
+ =C2=A0DEBUG ((REDFISH_DEBUG_TRACE, "%a provision for %s with: %s\n&q= uot;, __func__, ConfigureLang, (ProvisionMode ? L"Provision resource&q= uot; : L"Update resource")));
+
+ =C2=A0*ResultJson =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=3D NULL;
+ =C2=A0PropertyChanged =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=3D= FALSE;
+ =C2=A0AsciiStringValue =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=3D NULL= ;
+ =C2=A0SecureBootEnableDisable =3D RedfishReadSecureBootEnable ();
+ =C2=A0SecureBootEnabled =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=3D IsSecureB= ootEnabled ();
+
+ =C2=A0SecureBoot =3D NULL;
+ =C2=A0Status =C2=A0=C2=A0=C2=A0=C2=A0=3D JsonStructProtocol->ToStructu= re (
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0JsonSt= ructProtocol,
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0NULL,<= br> + =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0InputJ= son,
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0(EFI_R= EST_JSON_STRUCTURE_HEADER **)&SecureBoot
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0);
+ =C2=A0if (EFI_ERROR (Status)) {
+ =C2=A0=C2=A0=C2=A0DEBUG ((DEBUG_ERROR, "%a: ToStructure failure: %r\= n", __func__, Status));
+ =C2=A0=C2=A0=C2=A0return Status;
+ =C2=A0}
+
+ =C2=A0SecureBootCs =3D SecureBoot->SecureBoot;
+
+ =C2=A0//
+ =C2=A0// ID
+ =C2=A0//
+ =C2=A0if (SecureBootCs->Id !=3D NULL) {
+ =C2=A0=C2=A0=C2=A0SecureBootCs->Id =3D NULL;
+ =C2=A0}
+
+ =C2=A0//
+ =C2=A0// Name
+ =C2=A0//
+ =C2=A0if (SecureBootCs->Name !=3D NULL) {
+ =C2=A0=C2=A0=C2=A0SecureBootCs->Name =3D NULL;
+ =C2=A0}
+
+ =C2=A0//
+ =C2=A0// Secure boot variables that we will handle here
+ =C2=A0//
+ =C2=A0// EFI_SETUP_MODE_NAME (gEfiGlobalVariableGuid)
+ =C2=A0// EFI_SECURE_BOOT_MODE_NAME (gEfiGlobalVariableGuid)
+ =C2=A0// EFI_SECURE_BOOT_ENABLE_NAME (gEfiSecureBootEnableDisableGuid) + =C2=A0//
+
+ =C2=A0//
+ =C2=A0// Current Boot
+ =C2=A0//
+ =C2=A0if (PropertyChecker (SecureBootCs->SecureBootCurrentBoot, Provis= ionMode)) {
+ =C2=A0=C2=A0=C2=A0AsciiStringValue =3D AllocateZeroPool (SECURE_BOOT_MODE= _STR_LEN * sizeof (CHAR8));
+ =C2=A0=C2=A0=C2=A0if (AsciiStringValue !=3D NULL) {
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0AsciiSPrint (AsciiStringValue, SECURE_BOOT_= MODE_STR_LEN, "%a", (SecureBootEnabled ? SECURE_BOOT_ENABLED : SE= CURE_BOOT_DISABLED));
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0if (ProvisionMode || (AsciiStrCmp (SecureBo= otCs->SecureBootCurrentBoot, AsciiStringValue) !=3D 0)) {
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0SecureBootCs->SecureBootCurr= entBoot =3D AsciiStringValue;
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0PropertyChanged =C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=3D TRUE;
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0}
+ =C2=A0=C2=A0=C2=A0} else {
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0DEBUG ((DEBUG_ERROR, "%a: out of resou= rce\n", __func__));
+ =C2=A0=C2=A0=C2=A0}
+ =C2=A0}
+
+ =C2=A0//
+ =C2=A0// Secure boot enable
+ =C2=A0//
+ =C2=A0if (PropertyChecker (SecureBootCs->SecureBootEnable, ProvisionMo= de)) {
+ =C2=A0=C2=A0=C2=A0if (ProvisionMode || (*SecureBootCs->SecureBootEnabl= e !=3D SecureBootEnableDisable)) {
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0IntegerValue =3D AllocatePool (sizeof (*Int= egerValue));
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0if (IntegerValue !=3D NULL) {
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0*IntegerValue =C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=3D (SecureBootEnableDisable ? 0x01 : 0x00);
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0SecureBootCs->SecureBootEnab= le =3D IntegerValue;
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0PropertyChanged =C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =3D TRUE;
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0} else {
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0DEBUG ((DEBUG_ERROR, "%a: = out of resource\n", __func__));
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0}
+ =C2=A0=C2=A0=C2=A0}
+ =C2=A0}
+
+ =C2=A0//
+ =C2=A0// Secure boot mode
+ =C2=A0//
+ =C2=A0if (PropertyChecker (SecureBootCs->SecureBootMode, ProvisionMode= )) {
+ =C2=A0=C2=A0=C2=A0Status =3D GetSetupMode (&SetupMode);
+ =C2=A0=C2=A0=C2=A0if (!EFI_ERROR (Status)) {
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0AsciiStringValue =3D AllocateZeroPool (SECU= RE_BOOT_MODE_STR_LEN *sizeof (CHAR8));
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0if (AsciiStringValue !=3D NULL) {
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0AsciiSPrint (AsciiStringValue, = SECURE_BOOT_MODE_STR_LEN *sizeof (CHAR8), "%a", (SetupMode =3D=3D= USER_MODE ? SECURE_BOOT_USER_MODE : SECURE_BOOT_SETUP_MODE));
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0if (ProvisionMode || (AsciiStrC= mp (SecureBootCs->SecureBootMode, AsciiStringValue) !=3D 0)) {
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0SecureBootCs->Se= cureBootMode =3D AsciiStringValue;
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0PropertyChanged =C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =3D TRUE;
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0}
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0}
+ =C2=A0=C2=A0=C2=A0} else {
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0DEBUG ((DEBUG_ERROR, "%a: cannot read = setup mode: %r\n", __func__, Status));
+ =C2=A0=C2=A0=C2=A0}
+ =C2=A0}
+
+ =C2=A0//
+ =C2=A0// Convert C structure back to JSON text.
+ =C2=A0//
+ =C2=A0Status =3D JsonStructProtocol->ToJson (
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0JsonStructProtocol,
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0(EFI_REST_JSON_STRUCTURE_HEADE= R *)SecureBoot,
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0ResultJson
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0);
+ =C2=A0if (EFI_ERROR (Status)) {
+ =C2=A0=C2=A0=C2=A0DEBUG ((DEBUG_ERROR, "%a: ToJson() failed: %r\n&qu= ot;, __func__, Status));
+ =C2=A0=C2=A0=C2=A0return Status;

=C2=A0

=C2=A0

=C2=A0

=C2=A0 SecureBoot structure leak. It is released bel= ow.



+ =C2=A0}
+
+ =C2=A0//
+ =C2=A0// Release resource.
+ =C2=A0//
+ =C2=A0JsonStructProtocol->DestoryStructure (
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0JsonStruc= tProtocol,
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0(EFI_REST= _JSON_STRUCTURE_HEADER *)SecureBoot
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0);
+
+ =C2=A0return (PropertyChanged ? EFI_SUCCESS : EFI_NOT_FOUND);
+}
+
+/**
+ =C2=A0Provision Redfish resource and upload data to Redfish service. This= function
+ =C2=A0checks OEM data and platform addendum data before sending data to R= edfish service.
+
+ =C2=A0@param[in] =C2=A0=C2=A0Private =C2=A0=C2=A0Pointer to private data.=
+
+ =C2=A0@retval EFI_SUCCESS =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0Provision Redfish resource successfully. + =C2=A0@retval Others =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0Some error happene= d.
+
+**/
+EFI_STATUS
+ProvisioningSecureBootResource (
+ =C2=A0IN =C2=A0REDFISH_RESOURCE_COMMON_PRIVATE =C2=A0*Private
+ =C2=A0)
+{
+ =C2=A0EFI_STATUS =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0Status;
+ =C2=A0CHAR8 =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0*Json;
+ =C2=A0CHAR8 =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0*JsonWithAddendum;
+ =C2=A0REDFISH_RESPONSE =C2=A0Response;
+
+ =C2=A0if (Private =3D=3D NULL) {
+ =C2=A0=C2=A0=C2=A0return EFI_INVALID_PARAMETER;
+ =C2=A0}
+
+ =C2=A0ZeroMem (&Response, sizeof (REDFISH_RESPONSE));
+ =C2=A0Json =3D NULL;
+
+ =C2=A0Status =3D ProvisioningSecureBootProperties (
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0P= rivate->JsonStructProtocol,
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0S= ecureBootEmptyJson,
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0N= ULL,
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0R= EDFISH_DUMMY_CONFIG_LANG,
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0T= RUE,
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0&= amp;Json
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0)= ;
+ =C2=A0if (EFI_ERROR (Status)) {
+ =C2=A0=C2=A0=C2=A0if (Status =3D=3D EFI_NOT_FOUND) {
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0DEBUG ((REDFISH_DEBUG_TRACE, "%a: prov= isioning existing resource for %s ignored. Nothing changed\n", __func_= _, REDFISH_DUMMY_CONFIG_LANG));
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0Status =3D EFI_SUCCESS;
+ =C2=A0=C2=A0=C2=A0} else {
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0DEBUG ((DEBUG_ERROR, "%a: provisioning= existing resource for %s failed: %r\n", __func__, REDFISH_DUMMY_CONFI= G_LANG, Status));
+ =C2=A0=C2=A0=C2=A0}
+
+ =C2=A0=C2=A0=C2=A0goto ON_RELEASE;
+ =C2=A0}
+
+ =C2=A0//
+ =C2=A0// Check and see if platform has OEM data or not
+ =C2=A0//
+ =C2=A0Status =3D RedfishGetOemData (
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0P= rivate->Uri,
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0R= ESOURCE_SCHEMA,
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0R= ESOURCE_SCHEMA_VERSION,
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0J= son,
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0&= amp;JsonWithAddendum
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0)= ;
+ =C2=A0if (!EFI_ERROR (Status) && (JsonWithAddendum !=3D NULL)) {<= br> + =C2=A0=C2=A0=C2=A0FreePool (Json);
+ =C2=A0=C2=A0=C2=A0Json =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=3D JsonWithAddendum;
+ =C2=A0=C2=A0=C2=A0JsonWithAddendum =3D NULL;
+ =C2=A0}
+
+ =C2=A0//
+ =C2=A0// Check and see if platform has addendum data or not
+ =C2=A0//
+ =C2=A0Status =3D RedfishGetAddendumData (
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0P= rivate->Uri,
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0R= ESOURCE_SCHEMA,
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0R= ESOURCE_SCHEMA_VERSION,
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0J= son,
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0&= amp;JsonWithAddendum
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0)= ;
+ =C2=A0if (!EFI_ERROR (Status) && (JsonWithAddendum !=3D NULL)) {<= br> + =C2=A0=C2=A0=C2=A0FreePool (Json);
+ =C2=A0=C2=A0=C2=A0Json =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=3D JsonWithAddendum;
+ =C2=A0=C2=A0=C2=A0JsonWithAddendum =3D NULL;
+ =C2=A0}
+
+ =C2=A0DEBUG ((REDFISH_DEBUG_TRACE, "%a: provisioning existing resour= ce for %s\n", __func__, REDFISH_DUMMY_CONFIG_LANG));
+
+ =C2=A0//
+ =C2=A0// PATCH back to instance
+ =C2=A0//
+ =C2=A0Status =3D RedfishHttpPatchResource (Private->RedfishService, Pr= ivate->Uri, Json, &Response);
+ =C2=A0if (EFI_ERROR (Status)) {
+ =C2=A0=C2=A0=C2=A0DEBUG ((DEBUG_ERROR, "%a: patch resource for %s fa= iled: %r\n", __func__, REDFISH_DUMMY_CONFIG_LANG, Status));
+ =C2=A0}
+
+ON_RELEASE:
+
+ =C2=A0if (Json !=3D NULL) {
+ =C2=A0=C2=A0=C2=A0FreePool (Json);
+ =C2=A0}
+
+ =C2=A0RedfishHttpFreeResponse (&Response);
+
+ =C2=A0return Status;
+}
+
+/**
+ =C2=A0Provisioning redfish resource to Redfish service.
+
+ =C2=A0@param[in] =C2=A0=C2=A0Private =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0Pointer to private data.
+ =C2=A0@param[in] =C2=A0=C2=A0ResourceExist =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0TRUE if resource exists, PUT method will be used.
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0FALSE if resource = does not exist POST method is used.

=C2=A0

=C2=A0

Actually ProvisioningSecureBootResource uses PATCH o= nly.

=C2=A0



+
+ =C2=A0@retval EFI_SUCCESS =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0Provision resource successfully.
+ =C2=A0@retval Others =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0Some error happene= d.
+
+**/
+EFI_STATUS
+RedfishProvisioningResourceCommon (
+ =C2=A0IN =C2=A0=C2=A0=C2=A0=C2=A0REDFISH_RESOURCE_COMMON_PRIVATE =C2=A0*P= rivate,
+ =C2=A0IN =C2=A0=C2=A0=C2=A0=C2=A0BOOLEAN =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0ResourceExist
+ =C2=A0)
+{
+ =C2=A0if (Private =3D=3D NULL) {
+ =C2=A0=C2=A0=C2=A0return EFI_INVALID_PARAMETER;
+ =C2=A0}
+
+ =C2=A0return ProvisioningSecureBootResource (Private);
+}
+
+/**
+ =C2=A0Check resource from given Json data.
+
+ =C2=A0@param[in] =C2=A0=C2=A0This =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0Pointer to REDFISH_RESOU= RCE_COMMON_PRIVATE instance.
+ =C2=A0@param[in] =C2=A0=C2=A0Json =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0The JSON data to check.<= br> + =C2=A0@param[in] =C2=A0=C2=A0HeaderEtag =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0The Etag string returned in HTTP header.
+
+ =C2=A0@retval EFI_SUCCESS =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0Check resource successfully.
+ =C2=A0@retval Others =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0Some error happene= d.
+
+**/
+EFI_STATUS
+RedfishCheckResourceCommon (
+ =C2=A0IN =C2=A0=C2=A0=C2=A0=C2=A0REDFISH_RESOURCE_COMMON_PRIVATE =C2=A0*P= rivate,
+ =C2=A0IN =C2=A0=C2=A0=C2=A0=C2=A0CHAR8 =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0*Json,
+ =C2=A0IN =C2=A0=C2=A0=C2=A0=C2=A0CHAR8 =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0*HeaderEtag OPTIONAL<= br> + =C2=A0)
+{
+ =C2=A0UINTN =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0Index;
+ =C2=A0EFI_STATUS =C2=A0Status;
+ =C2=A0UINTN =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0Count;
+ =C2=A0EFI_STRING =C2=A0Property;
+
+ =C2=A0if ((Private =3D=3D NULL) || IS_EMPTY_STRING (Json)) {
+ =C2=A0=C2=A0=C2=A0return EFI_INVALID_PARAMETER;
+ =C2=A0}
+
+ =C2=A0//
+ =C2=A0// Check ETAG to see if we need to check it
+ =C2=A0//
+ =C2=A0if (CheckEtag (Private->Uri, HeaderEtag, NULL)) {
+ =C2=A0=C2=A0=C2=A0//
+ =C2=A0=C2=A0=C2=A0// No change
+ =C2=A0=C2=A0=C2=A0//
+ =C2=A0=C2=A0=C2=A0DEBUG ((REDFISH_DEBUG_TRACE, "%a: ETAG: %s has no = change, ignore check action\n", __func__, Private->Uri));
+ =C2=A0=C2=A0=C2=A0return EFI_SUCCESS;
+ =C2=A0}
+
+ =C2=A0Count =3D sizeof (mSecureBootSupportedAttributes) / sizeof (mSecure= BootSupportedAttributes[0]);
+ =C2=A0if (Count =3D=3D 0) {
+ =C2=A0=C2=A0=C2=A0return EFI_UNSUPPORTED;
+ =C2=A0}
+
+ =C2=A0Status =3D EFI_SUCCESS;
+ =C2=A0for (Index =3D 0; Index < Count; Index++) {
+ =C2=A0=C2=A0=C2=A0Property =3D mSecureBootSupportedAttributes[Index];
+ =C2=A0=C2=A0=C2=A0if (Property =3D=3D NULL) {
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0continue;
+ =C2=A0=C2=A0=C2=A0}
+
+ =C2=A0=C2=A0=C2=A0DEBUG ((REDFISH_DEBUG_TRACE, "%a: [%d] check attri= bute for: %s\n", __func__, Index, Property));
+ =C2=A0=C2=A0=C2=A0if (!MatchPropertyWithJsonContext (Property, Json)) { + =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0DEBUG ((REDFISH_DEBUG_TRACE, "%a: prop= erty is missing: %s\n", __func__, Property));
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0Status =3D EFI_NOT_FOUND;


Oh! I have a question about this condition.
Can we just break the loop here?
I'm asking mostly in c= ontext of Bios feature driver where the same loop exists.
While i= n this driver Count not greater than 3, but for Bios driver there could be = a hundreds of iterations
and AFAIR during provisioning we have EF= I_NOT_FOUND right after the first iteration.=C2=A0
MatchPropertyW= ithJsonContext() seems to be a heavy call.

The onl= y useful thing this loop does in that case is printing missed property if e= nabled.

+ =C2=A0=C2=A0=C2=A0}
+ =C2=A0}
+=C2=A0

+ =C2=A0return Status;
+}
+
+/**
+ =C2=A0Update resource to Redfish service.
+
+ =C2=A0@param[in] =C2=A0=C2=A0Private =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0Pointer to REDFISH_RESOURCE_COMMON_PRIV= ATE instance.
+ =C2=A0@param[in] =C2=A0=C2=A0Json =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0The JSON data to be upda= ted.
+
+ =C2=A0@retval EFI_SUCCESS =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0Update resource successfully.
+ =C2=A0@retval Others =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0Some error happene= d.
+
+**/
+EFI_STATUS
+RedfishUpdateResourceCommon (
+ =C2=A0IN =C2=A0=C2=A0=C2=A0=C2=A0REDFISH_RESOURCE_COMMON_PRIVATE =C2=A0*P= rivate,
+ =C2=A0IN =C2=A0=C2=A0=C2=A0=C2=A0CHAR8 =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0*InputJson
+ =C2=A0)
+{
+ =C2=A0EFI_STATUS =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0Status;
+ =C2=A0CHAR8 =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0*Json;
+ =C2=A0CHAR8 =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0*JsonWithAddendum;
+ =C2=A0REDFISH_RESPONSE =C2=A0Response;
+
+ =C2=A0if ((Private =3D=3D NULL) || IS_EMPTY_STRING (InputJson)) {
+ =C2=A0=C2=A0=C2=A0return EFI_INVALID_PARAMETER;
+ =C2=A0}
+
+ =C2=A0ZeroMem (&Response, sizeof (REDFISH_RESPONSE));
+ =C2=A0Json =3D NULL;
+
+ =C2=A0Status =3D ProvisioningSecureBootProperties (
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0P= rivate->JsonStructProtocol,
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0S= ecureBootEmptyJson,
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0N= ULL,
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0R= EDFISH_DUMMY_CONFIG_LANG,
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0T= RUE,
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0&= amp;Json
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0)= ;
+ =C2=A0if (EFI_ERROR (Status)) {
+ =C2=A0=C2=A0=C2=A0if (Status =3D=3D EFI_NOT_FOUND) {
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0DEBUG ((REDFISH_DEBUG_TRACE, "%a: upda= te resource for %s ignored. Nothing changed\n", __func__, REDFISH_DUMM= Y_CONFIG_LANG));
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0Status =3D EFI_SUCCESS;
+ =C2=A0=C2=A0=C2=A0} else {
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0DEBUG ((DEBUG_ERROR, "%a: update resou= rce for %s failed: %r\n", __func__, REDFISH_DUMMY_CONFIG_LANG, Status)= );
+ =C2=A0=C2=A0=C2=A0}
+
+ =C2=A0=C2=A0=C2=A0goto ON_RELEASE;
+ =C2=A0}
+
+ =C2=A0//
+ =C2=A0// Check and see if platform has OEM data or not
+ =C2=A0//
+ =C2=A0Status =3D RedfishGetOemData (
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0P= rivate->Uri,
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0R= ESOURCE_SCHEMA,
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0R= ESOURCE_SCHEMA_VERSION,
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0J= son,
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0&= amp;JsonWithAddendum
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0)= ;
+ =C2=A0if (!EFI_ERROR (Status) && (JsonWithAddendum !=3D NULL)) {<= br> + =C2=A0=C2=A0=C2=A0FreePool (Json);
+ =C2=A0=C2=A0=C2=A0Json =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=3D JsonWithAddendum;
+ =C2=A0=C2=A0=C2=A0JsonWithAddendum =3D NULL;
+ =C2=A0}
+
+ =C2=A0//
+ =C2=A0// Check and see if platform has addendum data or not
+ =C2=A0//
+ =C2=A0Status =3D RedfishGetAddendumData (
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0P= rivate->Uri,
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0R= ESOURCE_SCHEMA,
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0R= ESOURCE_SCHEMA_VERSION,
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0J= son,
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0&= amp;JsonWithAddendum
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0)= ;
+ =C2=A0if (!EFI_ERROR (Status) && (JsonWithAddendum !=3D NULL)) {<= br> + =C2=A0=C2=A0=C2=A0FreePool (Json);
+ =C2=A0=C2=A0=C2=A0Json =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=3D JsonWithAddendum;
+ =C2=A0=C2=A0=C2=A0JsonWithAddendum =3D NULL;
+ =C2=A0}
+
+ =C2=A0DEBUG ((REDFISH_DEBUG_TRACE, "%a: update resource for %s\n&quo= t;, __func__, REDFISH_DUMMY_CONFIG_LANG));
+
+ =C2=A0//
+ =C2=A0// PATCH back to instance
+ =C2=A0//
+ =C2=A0Status =3D RedfishHttpPatchResource (Private->RedfishService, Pr= ivate->Uri, Json, &Response);
+ =C2=A0if (EFI_ERROR (Status)) {
+ =C2=A0=C2=A0=C2=A0DEBUG ((DEBUG_ERROR, "%a: patch resource for %s fa= iled: %r\n", __func__, REDFISH_DUMMY_CONFIG_LANG, Status));
+ =C2=A0}
+
+ON_RELEASE:
+
+ =C2=A0if (Json !=3D NULL) {
+ =C2=A0=C2=A0=C2=A0FreePool (Json);
+ =C2=A0}
+
+ =C2=A0RedfishHttpFreeResponse (&Response);
+
+ =C2=A0return Status;
+}
+
+/**
+ =C2=A0Identify resource in given Json data.
+
+ =C2=A0@param[in] =C2=A0=C2=A0Private =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0Pointer to REDFISH_RESOURCE_COMMON_PRIV= ATE instance.
+ =C2=A0@param[in] =C2=A0=C2=A0Json =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0The JSON to be identifie= d.
+
+ =C2=A0@retval EFI_SUCCESS =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0Identify resource successfully.
+ =C2=A0@retval Others =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0Some error happene= d.
+
+**/
+EFI_STATUS
+RedfishIdentifyResourceCommon (
+ =C2=A0IN =C2=A0=C2=A0=C2=A0=C2=A0REDFISH_RESOURCE_COMMON_PRIVATE =C2=A0*P= rivate,
+ =C2=A0IN =C2=A0=C2=A0=C2=A0=C2=A0CHAR8 =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0*Json
+ =C2=A0)
+{
+ =C2=A0BOOLEAN =C2=A0Supported;
+
+ =C2=A0Supported =3D RedfishIdentifyResource (Private->Uri, Private->= ;Json);
+ =C2=A0if (Supported) {
+ =C2=A0=C2=A0=C2=A0//
+ =C2=A0=C2=A0=C2=A0// Keep URI and ConfigLang mapping
+ =C2=A0=C2=A0=C2=A0//
+ =C2=A0=C2=A0=C2=A0RedfishSetRedfishUri (REDFISH_DUMMY_CONFIG_LANG, Privat= e->Uri);
+ =C2=A0}
+
+ =C2=A0return (Supported ? EFI_SUCCESS : EFI_UNSUPPORTED);
+}
+
+/**
+ =C2=A0Handle Redfish resource in Uri.
+
+ =C2=A0@param[in] =C2=A0=C2=A0Private =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0Pointer to REDFISH_RESOURCE_COMMON_PRIV= ATE instance.
+ =C2=A0@param[in] =C2=A0=C2=A0Uri =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0URI to Redfish res= ource that we like to process.
+
+ =C2=A0@retval EFI_SUCCESS =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0Handle resource successfully.
+ =C2=A0@retval Others =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0Some error happene= d.
+
+**/
+EFI_STATUS
+HandleResource (
+ =C2=A0IN =C2=A0REDFISH_RESOURCE_COMMON_PRIVATE =C2=A0*Private,
+ =C2=A0IN =C2=A0EFI_STRING =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0Uri
+ =C2=A0)
+{
+ =C2=A0EFI_STATUS =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0Status;
+ =C2=A0REDFISH_SCHEMA_INFO =C2=A0SchemaInfo;
+ =C2=A0EFI_STRING =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0ConfigLang;
+
+ =C2=A0if ((Private =3D=3D NULL) || IS_EMPTY_STRING (Uri)) {
+ =C2=A0=C2=A0=C2=A0return EFI_INVALID_PARAMETER;
+ =C2=A0}
+
+ =C2=A0//
+ =C2=A0// Resource match
+ =C2=A0//
+
+ =C2=A0DEBUG ((REDFISH_DEBUG_TRACE, "%a: process resource for: %s\n&q= uot;, __func__, Uri));
+
+ =C2=A0Status =3D GetRedfishSchemaInfo (Private->RedfishService, Privat= e->JsonStructProtocol, Uri, NULL, &SchemaInfo);
+ =C2=A0if (EFI_ERROR (Status)) {
+ =C2=A0=C2=A0=C2=A0DEBUG ((DEBUG_ERROR, "%a: failed to get schema inf= ormation from: %s %r\n", __func__, Uri, Status));
+ =C2=A0=C2=A0=C2=A0return Status;
+ =C2=A0}
+
+ =C2=A0//
+ =C2=A0// Check and see if this is target resource that we want to handle.=
+ =C2=A0// Some resource is handled by other provider so we have to make su= re this first.
+ =C2=A0//
+ =C2=A0DEBUG ((REDFISH_DEBUG_TRACE, "%a: Identify for %s\n", __f= unc__, Uri));
+ =C2=A0ConfigLang =3D RedfishGetConfigLanguage (Uri);
+ =C2=A0if (ConfigLang =3D=3D NULL) {
+ =C2=A0=C2=A0=C2=A0Status =3D EdkIIRedfishResourceConfigIdentify (&Sch= emaInfo, Uri, NULL, Private->InformationExchange);
+ =C2=A0=C2=A0=C2=A0if (EFI_ERROR (Status)) {
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0if (Status =3D=3D EFI_UNSUPPORTED) {
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0DEBUG ((REDFISH_DEBUG_TRACE, &q= uot;%a: \"%s\" is not handled by us\n", __func__, Uri));
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0return EFI_SUCCESS;
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0} else if (Status =3D=3D EFI_NOT_FOUND) { + =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0DEBUG ((REDFISH_DEBUG_TRACE, &q= uot;%a: \"%s\" has nothing to handle\n", __func__, Uri)); + =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0return EFI_SUCCESS;
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0}
+
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0DEBUG ((DEBUG_ERROR, "%a: fail to iden= tify resource: \"%s\": %r\n", __func__, Uri, Status));
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0return Status;
+ =C2=A0=C2=A0=C2=A0}
+ =C2=A0} else {
+ =C2=A0=C2=A0=C2=A0DEBUG ((REDFISH_DEBUG_TRACE, "%a: history record f= ound: %s\n", __func__, ConfigLang));
+ =C2=A0=C2=A0=C2=A0FreePool (ConfigLang);
+ =C2=A0}
+
+ =C2=A0//
+ =C2=A0// Check and see if target property exist or not even when collecti= on member exists.
+ =C2=A0// If not, we sill do provision.

=C2=A0

%s/sill/still



+ =C2=A0//
+ =C2=A0DEBUG ((REDFISH_DEBUG_TRACE, "%a Check for %s\n", __func_= _, Uri));
+ =C2=A0Status =3D EdkIIRedfishResourceConfigCheck (&SchemaInfo, Uri, N= ULL);
+ =C2=A0if (EFI_ERROR (Status)) {
+ =C2=A0=C2=A0=C2=A0if (Status =3D=3D EFI_UNSUPPORTED) {
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0DEBUG ((REDFISH_DEBUG_TRACE, "%a: \&qu= ot;%s\" is not handled by us\n", __func__, Uri));
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0return EFI_SUCCESS;
+ =C2=A0=C2=A0=C2=A0}
+
+ =C2=A0=C2=A0=C2=A0//
+ =C2=A0=C2=A0=C2=A0// The target property does not exist, do the provision= to create property.
+ =C2=A0=C2=A0=C2=A0//
+ =C2=A0=C2=A0=C2=A0DEBUG ((REDFISH_DEBUG_TRACE, "%a provision for %s\= n", __func__, Uri));
+ =C2=A0=C2=A0=C2=A0Status =3D EdkIIRedfishResourceConfigProvisioning (&= ;SchemaInfo, Uri, NULL, Private->InformationExchange, FALSE);
+ =C2=A0=C2=A0=C2=A0if (EFI_ERROR (Status)) {
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0DEBUG ((DEBUG_ERROR, "%a: failed to pr= ovision with GET mode: %r\n", __func__, Status));
+ =C2=A0=C2=A0=C2=A0}
+
+ =C2=A0=C2=A0=C2=A0DEBUG ((REDFISH_DEBUG_TRACE, "%a: process resource= for: %s finished\n", __func__, Uri));
+
+ =C2=A0=C2=A0=C2=A0return Status;
+ =C2=A0}
+
+ =C2=A0//
+ =C2=A0// Consume first.
+ =C2=A0//
+ =C2=A0DEBUG ((REDFISH_DEBUG_TRACE, "%a consume for %s\n", __fun= c__, Uri));
+ =C2=A0Status =3D EdkIIRedfishResourceConfigConsume (&SchemaInfo, Uri,= NULL);
+ =C2=A0if (EFI_ERROR (Status)) {
+ =C2=A0=C2=A0=C2=A0DEBUG ((DEBUG_ERROR, "%a: failed to consume resour= ce for: %s: %r\n", __func__, Uri, Status));
+ =C2=A0}
+
+ =C2=A0//
+ =C2=A0// Patch.
+ =C2=A0//
+ =C2=A0DEBUG ((REDFISH_DEBUG_TRACE, "%a update for %s\n", __func= __, Uri));
+ =C2=A0Status =3D EdkIIRedfishResourceConfigUpdate (&SchemaInfo, Uri, = NULL);
+ =C2=A0if (EFI_ERROR (Status)) {
+ =C2=A0=C2=A0=C2=A0DEBUG ((DEBUG_ERROR, "%a: failed to update resourc= e for: %s: %r\n", __func__, Uri, Status));
+ =C2=A0}
+
+ =C2=A0DEBUG ((REDFISH_DEBUG_TRACE, "%a: process resource for: %s fin= ished\n", __func__, Uri));
+
+ =C2=A0return Status;
+}
diff --git a/RedfishClientPkg/Features/SecureBoot/v1_1_0/Dxe/SecureBootDxe.= c b/RedfishClientPkg/Features/SecureBoot/v1_1_0/Dxe/SecureBootDxe.c
new file mode 100644
index 000000000..a0f4f3d14
--- /dev/null
+++ b/RedfishClientPkg/Features/SecureBoot/v1_1_0/Dxe/SecureBootDxe.c
@@ -0,0 +1,808 @@
+/** @file
+ =C2=A0Redfish feature driver implementation - SecureBoot
+
+ =C2=A0(C) Copyright 2020-2022 Hewlett Packard Enterprise Development LP&l= t;BR>
+ =C2=A0Copyright (c) 2023, NVIDIA CORPORATION & AFFILIATES. All rights= reserved.
+
+ =C2=A0SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "../Common/SecureBootCommon.h"
+
+extern REDFISH_RESOURCE_COMMON_PRIVATE =C2=A0*mRedfishResourcePrivate;
+extern EFI_HANDLE =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0mRedfishResourceConfigProtocolHandle;
+
+EFI_STATUS
+HandleResource (
+ =C2=A0IN =C2=A0REDFISH_RESOURCE_COMMON_PRIVATE =C2=A0*Private,
+ =C2=A0IN =C2=A0EFI_STRING =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0Uri
+ =C2=A0);
+
+/**
+ =C2=A0Provisioning redfish resource by given URI.
+
+ =C2=A0@param[in] =C2=A0=C2=A0This =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0Pointer to EFI_HP_REDFIS= H_HII_PROTOCOL instance.
+ =C2=A0@param[in] =C2=A0=C2=A0Uri =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0Target URI to crea= te resource.
+ =C2=A0@param[in] =C2=A0=C2=A0PostMode =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0TRUE if the resource does not exist, post = method is used.
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0FALSE if the resou= rce exist but property is missing, put method is used.
+
+ =C2=A0@retval EFI_SUCCESS =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0Value is returned successfully.
+ =C2=A0@retval Others =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0Some error happene= d.
+
+**/
+EFI_STATUS
+EFIAPI
+RedfishResourceProvisioningResource (
+ =C2=A0IN =C2=A0=C2=A0=C2=A0=C2=A0EDKII_REDFISH_RESOURCE_CONFIG_PROTOCOL = =C2=A0*This,
+ =C2=A0IN =C2=A0=C2=A0=C2=A0=C2=A0EFI_STRING =C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0Uri= ,
+ =C2=A0IN =C2=A0=C2=A0=C2=A0=C2=A0BOOLEAN =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0PostMode
+ =C2=A0)
+{
+ =C2=A0REDFISH_RESOURCE_COMMON_PRIVATE =C2=A0*Private;
+ =C2=A0EFI_STATUS =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0Status;
+ =C2=A0REDFISH_RESPONSE =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0Response;
+
+ =C2=A0if ((This =3D=3D NULL) || IS_EMPTY_STRING (Uri)) {
+ =C2=A0=C2=A0=C2=A0return EFI_INVALID_PARAMETER;
+ =C2=A0}
+
+ =C2=A0DEBUG ((REDFISH_DEBUG_TRACE, "%a: provisioning in %s mode\n&qu= ot;, __func__, (PostMode ? L"POST" : L"PATCH")));

=C2=A0

=C2=A0

This message conflicts with PostMode parameter descr= iption.

=C2=A0



+
+ =C2=A0ZeroMem (&Response, sizeof (REDFISH_RESPONSE));
+ =C2=A0Private =3D REDFISH_RESOURCE_COMMON_PRIVATE_DATA_FROM_RESOURCE_PROT= OCOL (This);
+
+ =C2=A0if (Private->RedfishService =3D=3D NULL) {
+ =C2=A0=C2=A0=C2=A0return EFI_NOT_READY;
+ =C2=A0}
+
+ =C2=A0Status =3D RedfishHttpGetResource (Private->RedfishService, Uri,= NULL, &Response, TRUE);
+ =C2=A0if (EFI_ERROR (Status)) {
+ =C2=A0=C2=A0=C2=A0DEBUG ((DEBUG_ERROR, "%a: get resource from: %s fa= iled\n", __func__, Uri));
+ =C2=A0=C2=A0=C2=A0return Status;
+ =C2=A0}
+
+ =C2=A0Private->Uri =C2=A0=C2=A0=C2=A0=C2=A0=3D Uri;
+ =C2=A0Private->Payload =3D Response.Payload;
+ =C2=A0ASSERT (Private->Payload !=3D NULL);
+
+ =C2=A0Status =3D RedfishProvisioningResourceCommon (Private, !PostMode);<= br> + =C2=A0if (EFI_ERROR (Status)) {
+ =C2=A0=C2=A0=C2=A0DEBUG ((DEBUG_ERROR, "%a: failed to provision reso= urce to: %s: %r\n", __func__, Uri, Status));
+ =C2=A0} else {
+ =C2=A0=C2=A0=C2=A0//
+ =C2=A0=C2=A0=C2=A0// Get latest ETag on URI and keep it in variable.
+ =C2=A0=C2=A0=C2=A0//
+ =C2=A0=C2=A0=C2=A0SetEtagFromUri (Private->RedfishService, Private->= ;Uri, TRUE);
+ =C2=A0}
+
+ =C2=A0//
+ =C2=A0// Release resource
+ =C2=A0//
+ =C2=A0RedfishHttpFreeResponse (&Response);
+ =C2=A0Private->Payload =3D NULL;
+
+ =C2=A0return Status;
+}
+
+/**
+ =C2=A0Consume resource from given URI.
+
+ =C2=A0@param[in] =C2=A0=C2=A0This =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0Pointer to EFI_HP_REDFIS= H_HII_PROTOCOL instance.
+ =C2=A0@param[in] =C2=A0=C2=A0Uri =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0The target URI to = consume.
+
+ =C2=A0@retval EFI_SUCCESS =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0Value is returned successfully.
+ =C2=A0@retval Others =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0Some error happene= d.
+
+**/
+EFI_STATUS
+EFIAPI
+RedfishResourceConsumeResource (
+ =C2=A0IN =C2=A0=C2=A0=C2=A0=C2=A0EDKII_REDFISH_RESOURCE_CONFIG_PROTOCOL = =C2=A0*This,
+ =C2=A0IN =C2=A0=C2=A0=C2=A0=C2=A0EFI_STRING =C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0Uri=
+ =C2=A0)
+{
+ =C2=A0REDFISH_RESOURCE_COMMON_PRIVATE =C2=A0*Private;
+ =C2=A0EFI_STATUS =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0Status;
+ =C2=A0REDFISH_RESPONSE =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0Response;
+ =C2=A0EFI_STRING =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0PendingSettingUri;
+ =C2=A0REDFISH_RESPONSE =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0PendingSettingResponse;
+ =C2=A0REDFISH_RESPONSE =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0*ExpectedResponse;
+ =C2=A0CHAR8 =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0*Etag;
+
+ =C2=A0if ((This =3D=3D NULL) || IS_EMPTY_STRING (Uri)) {
+ =C2=A0=C2=A0=C2=A0return EFI_INVALID_PARAMETER;
+ =C2=A0}
+
+ =C2=A0ZeroMem (&Response, sizeof (REDFISH_RESPONSE));
+ =C2=A0ZeroMem (&PendingSettingResponse, sizeof (REDFISH_RESPONSE)); + =C2=A0Private =3D REDFISH_RESOURCE_COMMON_PRIVATE_DATA_FROM_RESOURCE_PROT= OCOL (This);
+
+ =C2=A0if (Private->RedfishService =3D=3D NULL) {
+ =C2=A0=C2=A0=C2=A0return EFI_NOT_READY;
+ =C2=A0}
+
+ =C2=A0Status =3D RedfishHttpGetResource (Private->RedfishService, Uri,= NULL, &Response, TRUE);
+ =C2=A0if (EFI_ERROR (Status)) {
+ =C2=A0=C2=A0=C2=A0DEBUG ((DEBUG_ERROR, "%a: get resource from: %s fa= iled\n", __func__, Uri));
+ =C2=A0=C2=A0=C2=A0return Status;
+ =C2=A0}
+
+ =C2=A0//
+ =C2=A0// Check and see if "@Redfish.Settings" exist or not.
+ =C2=A0//
+ =C2=A0PendingSettingUri =3D NULL;
+ =C2=A0Status =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=3D GetPendingSettings (
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0Private-&= gt;RedfishService,
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0Response.= Payload,
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0&Pend= ingSettingResponse,
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0&Pend= ingSettingUri
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0);
+ =C2=A0if (!EFI_ERROR (Status)) {
+ =C2=A0=C2=A0=C2=A0DEBUG ((REDFISH_DEBUG_TRACE, "%a: @Redfish.Setting= s found: %s\n", __func__, PendingSettingUri));
+ =C2=A0=C2=A0=C2=A0Private->Uri =C2=A0=C2=A0=C2=A0=C2=A0=3D PendingSett= ingUri;
+ =C2=A0=C2=A0=C2=A0ExpectedResponse =3D &PendingSettingResponse;
+ =C2=A0} else {
+ =C2=A0=C2=A0=C2=A0Private->Uri =C2=A0=C2=A0=C2=A0=C2=A0=3D Uri;
+ =C2=A0=C2=A0=C2=A0ExpectedResponse =3D &Response;
+ =C2=A0}
+
+ =C2=A0Private->Payload =3D ExpectedResponse->Payload;
+ =C2=A0ASSERT (Private->Payload !=3D NULL);
+
+ =C2=A0Private->Json =3D JsonDumpString (RedfishJsonInPayload (Private-= >Payload), EDKII_JSON_COMPACT);
+ =C2=A0ASSERT (Private->Json !=3D NULL);
+
+ =C2=A0//
+ =C2=A0// Searching for etag in HTTP response header
+ =C2=A0//
+ =C2=A0Etag =C2=A0=C2=A0=3D NULL;
+ =C2=A0Status =3D GetHttpResponseEtag (ExpectedResponse, &Etag);
+ =C2=A0if (EFI_ERROR (Status)) {
+ =C2=A0=C2=A0=C2=A0DEBUG ((DEBUG_ERROR, "%a: failed to get ETag from = HTTP header\n", __func__));
+ =C2=A0}
+
+ =C2=A0Status =3D RedfishConsumeResourceCommon (Private, Private->Json,= Etag);
+ =C2=A0if (EFI_ERROR (Status)) {
+ =C2=A0=C2=A0=C2=A0DEBUG ((DEBUG_ERROR, "%a: failed to consume resour= ce from: %s: %r\n", __func__, Private->Uri, Status));
+ =C2=A0}
+
+ =C2=A0//
+ =C2=A0// Release resource
+ =C2=A0//
+ =C2=A0RedfishHttpFreeResponse (&Response);
+ =C2=A0RedfishHttpFreeResponse (&PendingSettingResponse);
+ =C2=A0Private->Payload =3D NULL;
+
+ =C2=A0if (Private->Json !=3D NULL) {
+ =C2=A0=C2=A0=C2=A0FreePool (Private->Json);
+ =C2=A0=C2=A0=C2=A0Private->Json =3D NULL;
+ =C2=A0}
+
+ =C2=A0if (Etag !=3D NULL) {
+ =C2=A0=C2=A0=C2=A0FreePool (Etag);
+ =C2=A0}
+
+ =C2=A0if (PendingSettingUri !=3D NULL) {
+ =C2=A0=C2=A0=C2=A0FreePool (PendingSettingUri);
+ =C2=A0}
+
+ =C2=A0return Status;
+}
+
+/**
+ =C2=A0Get information about this protocol.
+
+ =C2=A0@param[in] =C2=A0=C2=A0This =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0Pointer to EFI_HP_REDFIS= H_HII_PROTOCOL instance.
+ =C2=A0@param[out] =C2=A0Schema =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0Supported schema.
+ =C2=A0@param[out] =C2=A0Major =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0Supported major number.
+ =C2=A0@param[out] =C2=A0Minor =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0Supported minor number.
+ =C2=A0@param[out] =C2=A0Errata =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0Supported errata number.
+
+ =C2=A0@retval EFI_SUCCESS =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0Value is returned successfully.
+ =C2=A0@retval Others =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0Some error happene= d.
+
+**/
+EFI_STATUS
+EFIAPI
+RedfishResourceGetInfo (
+ =C2=A0IN =C2=A0=C2=A0=C2=A0=C2=A0EDKII_REDFISH_RESOURCE_CONFIG_PROTOCOL = =C2=A0*This,
+ =C2=A0OUT =C2=A0=C2=A0=C2=A0REDFISH_SCHEMA_INFO =C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0*Info
+ =C2=A0)
+{
+ =C2=A0if ((This =3D=3D NULL) || (Info =3D=3D NULL)) {
+ =C2=A0=C2=A0=C2=A0return EFI_INVALID_PARAMETER;
+ =C2=A0}
+
+ =C2=A0AsciiStrCpyS (Info->Schema, REDFISH_SCHEMA_STRING_SIZE, RESOURCE= _SCHEMA);
+ =C2=A0AsciiStrCpyS (Info->Major, REDFISH_SCHEMA_VERSION_SIZE, RESOURCE= _SCHEMA_MAJOR);
+ =C2=A0AsciiStrCpyS (Info->Minor, REDFISH_SCHEMA_VERSION_SIZE, RESOURCE= _SCHEMA_MINOR);
+ =C2=A0AsciiStrCpyS (Info->Errata, REDFISH_SCHEMA_VERSION_SIZE, RESOURC= E_SCHEMA_ERRATA);
+
+ =C2=A0return EFI_SUCCESS;
+}
+
+/**
+ =C2=A0Update resource to given URI.
+
+ =C2=A0@param[in] =C2=A0=C2=A0This =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0Pointer to EFI_HP_REDFIS= H_HII_PROTOCOL instance.
+ =C2=A0@param[in] =C2=A0=C2=A0Uri =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0The target URI to = consume.
+
+ =C2=A0@retval EFI_SUCCESS =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0Value is returned successfully.
+ =C2=A0@retval Others =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0Some error happene= d.
+
+**/
+EFI_STATUS
+EFIAPI
+RedfishResourceUpdate (
+ =C2=A0IN =C2=A0=C2=A0=C2=A0=C2=A0EDKII_REDFISH_RESOURCE_CONFIG_PROTOCOL = =C2=A0*This,
+ =C2=A0IN =C2=A0=C2=A0=C2=A0=C2=A0EFI_STRING =C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0Uri=
+ =C2=A0)
+{
+ =C2=A0REDFISH_RESOURCE_COMMON_PRIVATE =C2=A0*Private;
+ =C2=A0EFI_STATUS =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0Status;
+ =C2=A0REDFISH_RESPONSE =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0Response;
+
+ =C2=A0if ((This =3D=3D NULL) || IS_EMPTY_STRING (Uri)) {
+ =C2=A0=C2=A0=C2=A0return EFI_INVALID_PARAMETER;
+ =C2=A0}
+
+ =C2=A0ZeroMem (&Response, sizeof (REDFISH_RESPONSE));
+ =C2=A0Private =3D REDFISH_RESOURCE_COMMON_PRIVATE_DATA_FROM_RESOURCE_PROT= OCOL (This);
+
+ =C2=A0if (Private->RedfishService =3D=3D NULL) {
+ =C2=A0=C2=A0=C2=A0return EFI_NOT_READY;
+ =C2=A0}
+
+ =C2=A0Status =3D RedfishHttpGetResource (Private->RedfishService, Uri,= NULL, &Response, TRUE);
+ =C2=A0if (EFI_ERROR (Status)) {
+ =C2=A0=C2=A0=C2=A0DEBUG ((DEBUG_ERROR, "%a: get resource from: %s fa= iled\n", __func__, Uri));
+ =C2=A0=C2=A0=C2=A0return Status;
+ =C2=A0}
+
+ =C2=A0Private->Uri =C2=A0=C2=A0=C2=A0=C2=A0=3D Uri;
+ =C2=A0Private->Payload =3D Response.Payload;
+ =C2=A0ASSERT (Private->Payload !=3D NULL);
+
+ =C2=A0Private->Json =3D JsonDumpString (RedfishJsonInPayload (Private-= >Payload), EDKII_JSON_COMPACT);
+ =C2=A0ASSERT (Private->Json !=3D NULL);
+
+ =C2=A0Status =3D RedfishUpdateResourceCommon (Private, Private->Json);=
+ =C2=A0if (EFI_ERROR (Status)) {
+ =C2=A0=C2=A0=C2=A0DEBUG ((DEBUG_ERROR, "%a: failed to update resourc= e to: %s: %r\n", __func__, Uri, Status));
+ =C2=A0} else {
+ =C2=A0=C2=A0=C2=A0//
+ =C2=A0=C2=A0=C2=A0// Get latest ETag on URI and keep it in variable.
+ =C2=A0=C2=A0=C2=A0//
+ =C2=A0=C2=A0=C2=A0SetEtagFromUri (Private->RedfishService, Private->= ;Uri, TRUE);
+ =C2=A0}
+
+ =C2=A0//
+ =C2=A0// Release resource
+ =C2=A0//
+ =C2=A0RedfishHttpFreeResponse (&Response);
+ =C2=A0Private->Payload =3D NULL;
+
+ =C2=A0if (Private->Json !=3D NULL) {
+ =C2=A0=C2=A0=C2=A0FreePool (Private->Json);
+ =C2=A0=C2=A0=C2=A0Private->Json =3D NULL;
+ =C2=A0}
+
+ =C2=A0return Status;
+}
+
+/**
+ =C2=A0Check resource on given URI.
+
+ =C2=A0@param[in] =C2=A0=C2=A0This =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0Pointer to EFI_HP_REDFIS= H_HII_PROTOCOL instance.
+ =C2=A0@param[in] =C2=A0=C2=A0Uri =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0The target URI to = consume.
+
+ =C2=A0@retval EFI_SUCCESS =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0Value is returned successfully.
+ =C2=A0@retval Others =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0Some error happene= d.
+
+**/
+EFI_STATUS
+EFIAPI
+RedfishResourceCheck (
+ =C2=A0IN =C2=A0=C2=A0=C2=A0=C2=A0EDKII_REDFISH_RESOURCE_CONFIG_PROTOCOL = =C2=A0*This,
+ =C2=A0IN =C2=A0=C2=A0=C2=A0=C2=A0EFI_STRING =C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0Uri=
+ =C2=A0)
+{
+ =C2=A0REDFISH_RESOURCE_COMMON_PRIVATE =C2=A0*Private;
+ =C2=A0EFI_STATUS =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0Status;
+ =C2=A0REDFISH_RESPONSE =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0Response;
+ =C2=A0CHAR8 =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0*Etag;
+
+ =C2=A0if ((This =3D=3D NULL) || IS_EMPTY_STRING (Uri)) {
+ =C2=A0=C2=A0=C2=A0return EFI_INVALID_PARAMETER;
+ =C2=A0}
+
+ =C2=A0ZeroMem (&Response, sizeof (REDFISH_RESPONSE));
+ =C2=A0Private =3D REDFISH_RESOURCE_COMMON_PRIVATE_DATA_FROM_RESOURCE_PROT= OCOL (This);
+
+ =C2=A0if (Private->RedfishService =3D=3D NULL) {
+ =C2=A0=C2=A0=C2=A0return EFI_NOT_READY;
+ =C2=A0}
+
+ =C2=A0Status =3D RedfishHttpGetResource (Private->RedfishService, Uri,= NULL, &Response, TRUE);
+ =C2=A0if (EFI_ERROR (Status)) {
+ =C2=A0=C2=A0=C2=A0DEBUG ((DEBUG_ERROR, "%a: get resource from: %s fa= iled\n", __func__, Uri));
+ =C2=A0=C2=A0=C2=A0return Status;
+ =C2=A0}
+
+ =C2=A0Private->Uri =C2=A0=C2=A0=C2=A0=C2=A0=3D Uri;
+ =C2=A0Private->Payload =3D Response.Payload;
+ =C2=A0ASSERT (Private->Payload !=3D NULL);
+
+ =C2=A0Private->Json =3D JsonDumpString (RedfishJsonInPayload (Private-= >Payload), EDKII_JSON_COMPACT);
+ =C2=A0ASSERT (Private->Json !=3D NULL);
+
+ =C2=A0//
+ =C2=A0// Find etag in HTTP response header
+ =C2=A0//
+ =C2=A0Etag =C2=A0=C2=A0=3D NULL;
+ =C2=A0Status =3D GetHttpResponseEtag (&Response, &Etag);
+ =C2=A0if (EFI_ERROR (Status)) {
+ =C2=A0=C2=A0=C2=A0DEBUG ((DEBUG_ERROR, "%a: failed to get ETag from = HTTP header\n", __func__));
+ =C2=A0}
+
+ =C2=A0Status =3D RedfishCheckResourceCommon (Private, Private->Json, E= tag);
+ =C2=A0if (EFI_ERROR (Status)) {
+ =C2=A0=C2=A0=C2=A0DEBUG ((DEBUG_ERROR, "%a: failed to check resource= from: %s: %r\n", __func__, Uri, Status));
+ =C2=A0}
+
+ =C2=A0//
+ =C2=A0// Release resource
+ =C2=A0//
+ =C2=A0if (Etag !=3D NULL) {
+ =C2=A0=C2=A0=C2=A0FreePool (Etag);
+ =C2=A0}
+
+ =C2=A0RedfishHttpFreeResponse (&Response);
+ =C2=A0Private->Payload =3D NULL;
+
+ =C2=A0if (Private->Json !=3D NULL) {
+ =C2=A0=C2=A0=C2=A0FreePool (Private->Json);
+ =C2=A0=C2=A0=C2=A0Private->Json =3D NULL;
+ =C2=A0}
+
+ =C2=A0return Status;
+}
+
+/**
+ =C2=A0Identify resource on given URI.
+
+ =C2=A0@param[in] =C2=A0=C2=A0This =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0Pointer to EDKII_REDFISH= _RESOURCE_CONFIG_PROTOCOL instance.
+ =C2=A0@param[in] =C2=A0=C2=A0Uri =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0The target URI to = consume.
+
+ =C2=A0@retval EFI_SUCCESS =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0This is target resource which we want to h= andle.
+ =C2=A0@retval EFI_UNSUPPORTED =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0This is not the target resource.
+ =C2=A0@retval Others =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0Some error happene= d.
+
+**/
+EFI_STATUS
+EFIAPI
+RedfishResourceIdentify (
+ =C2=A0IN =C2=A0=C2=A0=C2=A0=C2=A0EDKII_REDFISH_RESOURCE_CONFIG_PROTOCOL = =C2=A0*This,
+ =C2=A0IN =C2=A0=C2=A0=C2=A0=C2=A0EFI_STRING =C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0Uri=
+ =C2=A0)
+{
+ =C2=A0REDFISH_RESOURCE_COMMON_PRIVATE =C2=A0*Private;
+ =C2=A0EFI_STATUS =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0Status;
+ =C2=A0REDFISH_RESPONSE =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0Response;
+
+ =C2=A0if ((This =3D=3D NULL) || IS_EMPTY_STRING (Uri)) {
+ =C2=A0=C2=A0=C2=A0return EFI_INVALID_PARAMETER;
+ =C2=A0}
+
+ =C2=A0ZeroMem (&Response, sizeof (REDFISH_RESPONSE));
+ =C2=A0Private =3D REDFISH_RESOURCE_COMMON_PRIVATE_DATA_FROM_RESOURCE_PROT= OCOL (This);
+
+ =C2=A0if (Private->RedfishService =3D=3D NULL) {
+ =C2=A0=C2=A0=C2=A0return EFI_NOT_READY;
+ =C2=A0}
+
+ =C2=A0Status =3D RedfishHttpGetResource (Private->RedfishService, Uri,= NULL, &Response, TRUE);
+ =C2=A0if (EFI_ERROR (Status)) {
+ =C2=A0=C2=A0=C2=A0DEBUG ((DEBUG_ERROR, "%a: get resource from: %s fa= iled\n", __func__, Uri));
+ =C2=A0=C2=A0=C2=A0return Status;
+ =C2=A0}
+
+ =C2=A0Private->Uri =C2=A0=C2=A0=C2=A0=C2=A0=3D Uri;
+ =C2=A0Private->Payload =3D Response.Payload;
+ =C2=A0ASSERT (Private->Payload !=3D NULL);
+
+ =C2=A0Private->Json =3D JsonDumpString (RedfishJsonInPayload (Private-= >Payload), EDKII_JSON_COMPACT);
+ =C2=A0ASSERT (Private->Json !=3D NULL);
+
+ =C2=A0Status =3D RedfishIdentifyResourceCommon (Private, Private->Json= );
+ =C2=A0if (EFI_ERROR (Status)) {
+ =C2=A0=C2=A0=C2=A0DEBUG ((DEBUG_ERROR, "%a: identify %s failed: %r\n= ", __func__, Uri, Status));
+ =C2=A0}
+
+ =C2=A0//
+ =C2=A0// Release resource
+ =C2=A0//
+ =C2=A0RedfishHttpFreeResponse (&Response);
+ =C2=A0Private->Payload =3D NULL;
+
+ =C2=A0if (Private->Json !=3D NULL) {
+ =C2=A0=C2=A0=C2=A0FreePool (Private->Json);
+ =C2=A0=C2=A0=C2=A0Private->Json =3D NULL;
+ =C2=A0}
+
+ =C2=A0return Status;
+}
+
+EDKII_REDFISH_RESOURCE_CONFIG_PROTOCOL =C2=A0mRedfishResourceConfig =3D {<= br> + =C2=A0RedfishResourceProvisioningResource,
+ =C2=A0RedfishResourceConsumeResource,
+ =C2=A0RedfishResourceUpdate,
+ =C2=A0RedfishResourceCheck,
+ =C2=A0RedfishResourceIdentify,
+ =C2=A0RedfishResourceGetInfo
+};
+
+/**
+ =C2=A0Initialize a Redfish configure handler.
+
+ =C2=A0This function will be called by the Redfish config driver to initia= lize each Redfish configure
+ =C2=A0handler.
+
+ =C2=A0@param[in] =C2=A0=C2=A0This =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0Pointer to EDKII_REDFISH_CONFIG_HANDLER_PROTOCOL instance.
+ =C2=A0@param[in] =C2=A0=C2=A0RedfishConfigServiceInfo Redfish service inf= ormation.
+
+ =C2=A0@retval EFI_SUCCESS =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0The handler has be= en initialized successfully.
+ =C2=A0@retval EFI_DEVICE_ERROR =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0Failed to create or configure the REST EX pro= tocol instance.
+ =C2=A0@retval EFI_ALREADY_STARTED =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0This handler has already been initialized.
+ =C2=A0@retval Other =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0Error happens during the initialization.
+
+**/
+EFI_STATUS
+EFIAPI
+RedfishResourceInit (
+ =C2=A0IN =C2=A0EDKII_REDFISH_CONFIG_HANDLER_PROTOCOL =C2=A0*This,
+ =C2=A0IN =C2=A0REDFISH_CONFIG_SERVICE_INFORMATION =C2=A0=C2=A0=C2=A0=C2= =A0*RedfishConfigServiceInfo
+ =C2=A0)
+{
+ =C2=A0REDFISH_RESOURCE_COMMON_PRIVATE =C2=A0*Private;
+
+ =C2=A0Private =3D REDFISH_RESOURCE_COMMON_PRIVATE_DATA_FROM_CONFIG_PROTOC= OL (This);
+
+ =C2=A0Private->RedfishService =3D RedfishCreateService (RedfishConfigS= erviceInfo);
+ =C2=A0if (Private->RedfishService =3D=3D NULL) {
+ =C2=A0=C2=A0=C2=A0return EFI_DEVICE_ERROR;
+ =C2=A0}
+
+ =C2=A0return EFI_SUCCESS;
+}
+
+/**
+ =C2=A0Stop a Redfish configure handler.
+
+ =C2=A0@param[in] =C2=A0=C2=A0This =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0Pointer to EDKII_REDFISH= _CONFIG_HANDLER_PROTOCOL instance.
+
+ =C2=A0@retval EFI_SUCCESS =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0This handler has been stoped successfully.=
+ =C2=A0@retval Others =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0Some error happene= d.
+
+**/
+EFI_STATUS
+EFIAPI
+RedfishResourceStop (
+ =C2=A0IN =C2=A0EDKII_REDFISH_CONFIG_HANDLER_PROTOCOL =C2=A0*This
+ =C2=A0)
+{
+ =C2=A0REDFISH_RESOURCE_COMMON_PRIVATE =C2=A0*Private;
+
+ =C2=A0Private =3D REDFISH_RESOURCE_COMMON_PRIVATE_DATA_FROM_CONFIG_PROTOC= OL (This);
+
+ =C2=A0if (Private->Event !=3D NULL) {
+ =C2=A0=C2=A0=C2=A0gBS->CloseEvent (Private->Event);
+ =C2=A0=C2=A0=C2=A0Private->Event =3D NULL;
+ =C2=A0}
+
+ =C2=A0if (Private->RedfishService !=3D NULL) {
+ =C2=A0=C2=A0=C2=A0RedfishCleanupService (Private->RedfishService);
+ =C2=A0=C2=A0=C2=A0Private->RedfishService =3D NULL;
+ =C2=A0}
+
+ =C2=A0return EFI_SUCCESS;
+}
+
+EDKII_REDFISH_CONFIG_HANDLER_PROTOCOL =C2=A0mRedfishConfigHandler =3D { + =C2=A0RedfishResourceInit,
+ =C2=A0RedfishResourceStop
+};
+
+/**
+ =C2=A0Callback function when gEfiRestJsonStructureProtocolGuid is install= ed.
+
+ =C2=A0@param[in] Event =C2=A0=C2=A0=C2=A0Event whose notification functio= n is being invoked.
+ =C2=A0@param[in] Context =C2=A0Pointer to the notification function's= context.
+**/
+VOID
+EFIAPI
+EfiRestJsonStructureProtocolIsReady (
+ =C2=A0IN =C2=A0EFI_EVENT =C2=A0Event,
+ =C2=A0IN =C2=A0VOID =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0*Context
+ =C2=A0)
+{
+ =C2=A0EFI_STATUS =C2=A0Status;
+
+ =C2=A0if (mRedfishResourcePrivate =3D=3D NULL) {
+ =C2=A0=C2=A0=C2=A0return;
+ =C2=A0}
+
+ =C2=A0if (mRedfishResourcePrivate->JsonStructProtocol !=3D NULL) {
+ =C2=A0=C2=A0=C2=A0return;
+ =C2=A0}
+
+ =C2=A0Status =3D gBS->LocateProtocol (
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0&gEfiRestJsonStructureProtocolGuid,
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0NULL,
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0(VOID **)&mRedfishResourcePrivate->Jso= nStructProtocol
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0);
+ =C2=A0if (EFI_ERROR (Status)) {
+ =C2=A0=C2=A0=C2=A0DEBUG ((DEBUG_ERROR, "%a: failed to locate gEfiRes= tJsonStructureProtocolGuid: %r\n", __func__, Status));
+ =C2=A0}
+
+ =C2=A0gBS->CloseEvent (Event);
+}
+
+/**
+ =C2=A0Unloads an image.
+
+ =C2=A0@param =C2=A0ImageHandle =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0Handle that identifies the image to be unloaded.
+
+ =C2=A0@retval EFI_SUCCESS =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0The image has been unloaded.
+ =C2=A0@retval EFI_INVALID_PARAMETER ImageHandle is not a valid image hand= le.
+
+**/
+EFI_STATUS
+EFIAPI
+RedfishResourceUnload (
+ =C2=A0IN EFI_HANDLE =C2=A0ImageHandle
+ =C2=A0)
+{
+ =C2=A0EFI_STATUS =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0Status;
+ =C2=A0EDKII_REDFISH_CONFIG_HANDLER_PROTOCOL =C2=A0*ConfigHandler;
+
+ =C2=A0if (mRedfishResourcePrivate =3D=3D NULL) {
+ =C2=A0=C2=A0=C2=A0return EFI_NOT_READY;
+ =C2=A0}
+
+ =C2=A0ConfigHandler =3D NULL;
+
+ =C2=A0//
+ =C2=A0// Firstly, find ConfigHandler Protocol interface in this ImageHand= le.
+ =C2=A0//
+ =C2=A0Status =3D gBS->OpenProtocol (
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0ImageHandle,
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0&gEdkIIRedfishConfigHandlerProtocolGuid,<= br> + =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0(VOID **)&ConfigHandler,
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0NULL,
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0NULL,
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0);
+ =C2=A0if (EFI_ERROR (Status) || (ConfigHandler =3D=3D NULL)) {
+ =C2=A0=C2=A0=C2=A0return Status;
+ =C2=A0}
+
+ =C2=A0ConfigHandler->Stop (ConfigHandler);
+
+ =C2=A0//
+ =C2=A0// Last, uninstall ConfigHandler Protocol and resource protocol. + =C2=A0//
+ =C2=A0Status =3D gBS->UninstallMultipleProtocolInterfaces (
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0ImageHandle,
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0&gEdkIIRedfishConfigHandlerProtocolGuid,<= br> + =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0ConfigHandler,
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0&gEdkIIRedfishResourceConfigProtocolGuid,=
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0&mRedfishResourcePrivate->RedfishResou= rceConfig,
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0NULL
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0);
+
+ =C2=A0FreePool (mRedfishResourcePrivate);
+ =C2=A0mRedfishResourcePrivate =3D NULL;
+
+ =C2=A0return Status;
+}
+
+/**
+ =C2=A0The callback function provided by Redfish Feature driver.
+
+ =C2=A0@param[in] =C2=A0=C2=A0=C2=A0=C2=A0This =C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0Pointer to E= DKII_REDFISH_FEATURE_PROTOCOL instance.
+ =C2=A0@param[in] =C2=A0=C2=A0=C2=A0=C2=A0FeatureAction =C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0The action Redfish feature driver should take.
+ =C2=A0@param[in] =C2=A0=C2=A0=C2=A0=C2=A0Uri =C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0The co= llection URI.
+ =C2=A0@param[in] =C2=A0=C2=A0=C2=A0=C2=A0Context =C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0The context of Redfish feat= ure driver.
+ =C2=A0@param[in,out] InformationExchange The pointer to RESOURCE_INFORMAT= ION_EXCHANGE
+
+ =C2=A0@retval EFI_SUCCESS =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0Redfish feature driver callback is execute= d successfully.
+ =C2=A0@retval Others =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0Some errors happen= ed.
+
+ =C2=A0@retval EFI_SUCCESS =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0Redfish feature driver callback is execute= d successfully.
+ =C2=A0@retval Others =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0Some errors happen= ed.
+
+**/
+EFI_STATUS
+EFIAPI
+RedfishExternalResourceResourceFeatureCallback (
+ =C2=A0IN =C2=A0=C2=A0=C2=A0=C2=A0EDKII_REDFISH_FEATURE_PROTOCOL =C2=A0*Th= is,
+ =C2=A0IN =C2=A0=C2=A0=C2=A0=C2=A0FEATURE_CALLBACK_ACTION =C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0FeatureAction,
+ =C2=A0IN =C2=A0=C2=A0=C2=A0=C2=A0VOID =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0*Context,
+ =C2=A0IN OUT RESOURCE_INFORMATION_EXCHANGE =C2=A0=C2=A0*InformationExchan= ge
+ =C2=A0)
+{
+ =C2=A0EFI_STATUS =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0Status;
+ =C2=A0REDFISH_SERVICE =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0RedfishService;
+ =C2=A0REDFISH_RESOURCE_COMMON_PRIVATE =C2=A0*Private;
+ =C2=A0EFI_STRING =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0ResourceUri;
+ =C2=A0EFI_STRING =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0SecureBootUri;
+
+ =C2=A0if (FeatureAction !=3D CallbackActionStartOperation) {
+ =C2=A0=C2=A0=C2=A0return EFI_UNSUPPORTED;
+ =C2=A0}
+
+ =C2=A0Private =3D (REDFISH_RESOURCE_COMMON_PRIVATE *)Context;
+
+ =C2=A0RedfishService =3D Private->RedfishService;
+ =C2=A0if (RedfishService =3D=3D NULL) {
+ =C2=A0=C2=A0=C2=A0DEBUG ((DEBUG_ERROR, "%a: no Redfish service confi= gured\n", __func__));
+ =C2=A0=C2=A0=C2=A0return EFI_NOT_READY;
+ =C2=A0}
+
+ =C2=A0//
+ =C2=A0// Save in private structure.
+ =C2=A0//
+ =C2=A0Private->InformationExchange =3D InformationExchange;
+
+ =C2=A0//
+ =C2=A0// Find Redfish version on Redfish ser
+ =C2=A0//
+ =C2=A0Private->RedfishVersion =3D RedfishGetVersion (RedfishService);<= br> +
+ =C2=A0//
+ =C2=A0// Create the full URI from Redfish service root.
+ =C2=A0//
+ =C2=A0ResourceUri =3D (EFI_STRING)AllocateZeroPool (MAX_URI_LENGTH * size= of (CHAR16));
+ =C2=A0if (ResourceUri =3D=3D NULL) {
+ =C2=A0=C2=A0=C2=A0DEBUG ((DEBUG_ERROR, "%a: Fail to allocate memory = for full URI.\n", __func__));
+ =C2=A0=C2=A0=C2=A0return EFI_OUT_OF_RESOURCES;
+ =C2=A0}
+
+ =C2=A0StrCatS (ResourceUri, MAX_URI_LENGTH, Private->RedfishVersion);<= br> + =C2=A0StrCatS (ResourceUri, MAX_URI_LENGTH, InformationExchange->SendI= nformation.FullUri);
+
+ =C2=A0//
+ =C2=A0// Initialize collection path
+ =C2=A0//
+ =C2=A0SecureBootUri =3D RedfishGetUri (ResourceUri);
+ =C2=A0if (SecureBootUri =3D=3D NULL) {
+ =C2=A0=C2=A0=C2=A0ASSERT (FALSE);
+ =C2=A0=C2=A0=C2=A0FreePool (ResourceUri);
+ =C2=A0=C2=A0=C2=A0return EFI_OUT_OF_RESOURCES;
+ =C2=A0}
+
+ =C2=A0Status =3D HandleResource (Private, SecureBootUri);
+ =C2=A0if (EFI_ERROR (Status)) {
+ =C2=A0=C2=A0=C2=A0DEBUG ((DEBUG_ERROR, "%a: process external resourc= e: %s failed: %r\n", __func__, SecureBootUri, Status));
+ =C2=A0}
+
+ =C2=A0FreePool (SecureBootUri);
+ =C2=A0FreePool (ResourceUri);
+ =C2=A0return Status;
+}
+
+/**
+ =C2=A0Callback function when gEdkIIRedfishFeatureProtocolGuid is installe= d.
+
+ =C2=A0@param[in] Event =C2=A0=C2=A0=C2=A0Event whose notification functio= n is being invoked.
+ =C2=A0@param[in] Context =C2=A0Pointer to the notification function's= context.
+**/
+VOID
+EFIAPI
+EdkIIRedfishFeatureProtocolIsReady (
+ =C2=A0IN =C2=A0EFI_EVENT =C2=A0Event,
+ =C2=A0IN =C2=A0VOID =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0*Context
+ =C2=A0)
+{
+ =C2=A0EFI_STATUS =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0Sta= tus;
+ =C2=A0EDKII_REDFISH_FEATURE_PROTOCOL =C2=A0*FeatureProtocol;
+
+ =C2=A0if (mRedfishResourcePrivate =3D=3D NULL) {
+ =C2=A0=C2=A0=C2=A0return;
+ =C2=A0}
+
+ =C2=A0if (mRedfishResourcePrivate->FeatureProtocol !=3D NULL) {
+ =C2=A0=C2=A0=C2=A0return;
+ =C2=A0}
+
+ =C2=A0Status =3D gBS->LocateProtocol (
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0&gEdkIIRedfishFeatureProtocolGuid,
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0NULL,
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0(VOID **)&FeatureProtocol
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0);
+ =C2=A0if (EFI_ERROR (Status)) {
+ =C2=A0=C2=A0=C2=A0DEBUG ((DEBUG_ERROR, "%a: failed to locate gEdkIIR= edfishFeatureProtocolGuid: %r\n", __func__, Status));
+ =C2=A0=C2=A0=C2=A0gBS->CloseEvent (Event);
+ =C2=A0=C2=A0=C2=A0return;
+ =C2=A0}
+
+ =C2=A0Status =3D FeatureProtocol->Register (
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0FeatureProtocol,
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0REDFISH_MANAGED_URI,
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0RedfishExternalResourceResourceFeatureCallback,<= br> + =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0(VOID *)mRedfishResourcePrivate
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0);
+ =C2=A0if (EFI_ERROR (Status)) {
+ =C2=A0=C2=A0=C2=A0DEBUG ((DEBUG_ERROR, "%a: failed to register %s: %= r\n", __func__, REDFISH_MANAGED_URI, Status));
+ =C2=A0}
+
+ =C2=A0mRedfishResourcePrivate->FeatureProtocol =3D FeatureProtocol; +
+ =C2=A0gBS->CloseEvent (Event);
+}
+
+/**
+ =C2=A0This is the declaration of an EFI image entry point. This entry poi= nt is
+ =C2=A0the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers i= ncluding
+ =C2=A0both device drivers and bus drivers. It initialize the global varia= bles and
+ =C2=A0publish the driver binding protocol.
+
+ =C2=A0@param[in] =C2=A0=C2=A0ImageHandle =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0Th= e firmware allocated handle for the UEFI image.
+ =C2=A0@param[in] =C2=A0=C2=A0SystemTable =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0A = pointer to the EFI System Table.
+
+ =C2=A0@retval EFI_SUCCESS =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0The operation completed successfully.
+ =C2=A0@retval EFI_ACCESS_DENIED =C2=A0=C2=A0=C2=A0=C2=A0EFI_ISCSI_INITIAT= OR_NAME_PROTOCOL was installed unexpectedly.
+ =C2=A0@retval Others =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0Other errors as indicated.
+**/
+EFI_STATUS
+EFIAPI
+RedfishResourceEntryPoint (
+ =C2=A0IN EFI_HANDLE =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0ImageHandle= ,
+ =C2=A0IN EFI_SYSTEM_TABLE =C2=A0*SystemTable
+ =C2=A0)
+{
+ =C2=A0EFI_STATUS =C2=A0Status;
+ =C2=A0VOID =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0*Registration;
+
+ =C2=A0if (mRedfishResourcePrivate !=3D NULL) {
+ =C2=A0=C2=A0=C2=A0return EFI_ALREADY_STARTED;
+ =C2=A0}
+
+ =C2=A0mRedfishResourceConfigProtocolHandle =3D ImageHandle;
+
+ =C2=A0mRedfishResourcePrivate =3D AllocateZeroPool (sizeof (REDFISH_RESOU= RCE_COMMON_PRIVATE));
+ =C2=A0CopyMem (&mRedfishResourcePrivate->ConfigHandler, &mRedf= ishConfigHandler, sizeof (EDKII_REDFISH_CONFIG_HANDLER_PROTOCOL));
+ =C2=A0CopyMem (&mRedfishResourcePrivate->RedfishResourceConfig, &a= mp;mRedfishResourceConfig, sizeof (EDKII_REDFISH_RESOURCE_CONFIG_PROTOCOL))= ;
+
+ =C2=A0//
+ =C2=A0// Publish config handler protocol and resource protocol.
+ =C2=A0//
+ =C2=A0Status =3D gBS->InstallMultipleProtocolInterfaces (
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0&ImageHandle,
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0&gEdkIIRedfishConfigHandlerProtocolGuid,<= br> + =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0&mRedfishResourcePrivate->ConfigHandle= r,
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0&gEdkIIRedfishResourceConfigProtocolGuid,=
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0&mRedfishResourcePrivate->RedfishResou= rceConfig,
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0NULL
+ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0);
+
+ =C2=A0EfiCreateProtocolNotifyEvent (
+ =C2=A0=C2=A0=C2=A0&gEfiRestJsonStructureProtocolGuid,
+ =C2=A0=C2=A0=C2=A0TPL_CALLBACK,
+ =C2=A0=C2=A0=C2=A0EfiRestJsonStructureProtocolIsReady,
+ =C2=A0=C2=A0=C2=A0NULL,
+ =C2=A0=C2=A0=C2=A0&Registration
+ =C2=A0=C2=A0=C2=A0);
+
+ =C2=A0EfiCreateProtocolNotifyEvent (
+ =C2=A0=C2=A0=C2=A0&gEdkIIRedfishFeatureProtocolGuid,
+ =C2=A0=C2=A0=C2=A0TPL_CALLBACK,
+ =C2=A0=C2=A0=C2=A0EdkIIRedfishFeatureProtocolIsReady,
+ =C2=A0=C2=A0=C2=A0(VOID *)mRedfishResourcePrivate,
+ =C2=A0=C2=A0=C2=A0&Registration
+ =C2=A0=C2=A0=C2=A0);
+
+ =C2=A0return Status;
+}
diff --git a/RedfishClientPkg/RedfishClient.fdf.inc b/RedfishClientPkg/Redf= ishClient.fdf.inc
index 59b8acba1..154f641b2 100644
--- a/RedfishClientPkg/RedfishClient.fdf.inc
+++ b/RedfishClientPkg/RedfishClient.fdf.inc
@@ -25,6 +25,7 @@
=C2=A0=C2=A0INF RedfishClientPkg/HiiToRedfishBiosDxe/HiiToRedfishBiosDxe.in= f
=C2=A0=C2=A0INF RedfishClientPkg/Features/BootOptionCollection/BootOptionCo= llectionDxe.inf
=C2=A0=C2=A0INF RedfishClientPkg/Features/BootOption/v1_0_4/Dxe/BootOptionD= xe.inf
+ =C2=A0INF RedfishClientPkg/Features/SecureBoot/v1_1_0/Dxe/SecureBootDxe.i= nf

=C2=A0=C2=A0!include RedfishClientPkg/RedfishJsonStructureDxe.fdf.inc
=C2=A0=C2=A0#
--
2.34.1

=C2=A0

=C2=A0

=C2=A0

Regards,

Mike

=C2=A0


Regards,
Mike.
=C2=A0=C2=A0
_._,_._,_

Groups.io Links:

=20 You receive all messages sent to this group. =20 =20

View/Reply Online (#117142) | =20 | Mute= This Topic | New Topic
Your Subscriptio= n | Contact Group Owner | Unsubscribe [rebecca@openfw.io]

_._,_._,_
--000000000000c65f1206149836c7--