From nobody Sun May 5 20:15:32 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) client-ip=66.175.222.108; envelope-from=bounce+27952+91795+1787277+3901457@groups.io; helo=mail02.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+91795+1787277+3901457@groups.io; dmarc=fail(p=none dis=none) header.from=hpe.com ARC-Seal: i=1; a=rsa-sha256; t=1658719468; cv=none; d=zohomail.com; s=zohoarc; b=BsIGCwCjvI9GcpqCqgsXx43KXvIMiQupczEcOh6UA6VNjCkzBjrBrBHS/ZD+IQxuetnphKovs/z6CWJllkUp6fuXEN27FP9e0W9oe0PXlqixZkkNzL9fvDMvYXe9Ho64tbA+PrCJP7QieaT+3pTGd58P/Bdr32SksT66hlC0xxo= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1658719468; h=Content-Transfer-Encoding:Cc:Date:From:List-Subscribe:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:Sender:Subject:To; bh=9UExESGEppt2RodrlWGnX10pJEw7c3UOyzp2tNbigGk=; b=ElKn6l8C48XdjgEHCIrJUuyDYxilp7GrDPOWcspruPdhlz2KgIIG1Ha6rizfZ/1p27k3d3oqpyiiWqyYKaEWVhbRD6X5evhZx0gTD/KX26ZhJSZGZmIaarEUO0kC/vE8ZYfjSwHkg8KBZs8o9J8QIyb/Tbe/8RFcSXtA8qTd9ys= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+91795+1787277+3901457@groups.io; dmarc=fail header.from= (p=none dis=none) Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 1658719468606188.07589908169325; Sun, 24 Jul 2022 20:24:28 -0700 (PDT) Return-Path: X-Received: by 127.0.0.2 with SMTP id EUUJYY1788612xnZ2N1GHeaH; Sun, 24 Jul 2022 20:24:28 -0700 X-Received: from mx0b-002e3701.pphosted.com (mx0b-002e3701.pphosted.com [148.163.143.35]) by mx.groups.io with SMTP id smtpd.web09.24122.1658719466694042415 for ; Sun, 24 Jul 2022 20:24:27 -0700 X-Received: from pps.filterd (m0150244.ppops.net [127.0.0.1]) by mx0b-002e3701.pphosted.com (8.17.1.5/8.17.1.5) with ESMTP id 26OJepHB023860; Mon, 25 Jul 2022 03:24:24 GMT X-Received: from p1lg14879.it.hpe.com (p1lg14879.it.hpe.com [16.230.97.200]) by mx0b-002e3701.pphosted.com (PPS) with ESMTPS id 3hhceqt6aa-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 25 Jul 2022 03:24:23 +0000 X-Received: from p1lg14885.dc01.its.hpecorp.net (unknown [10.119.18.236]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by p1lg14879.it.hpe.com (Postfix) with ESMTPS id 25F41132D1; Mon, 25 Jul 2022 03:24:23 +0000 (UTC) X-Received: from WAFM3XJD5N.asiapacific.hpqcorp.net (unknown [16.231.227.36]) by p1lg14885.dc01.its.hpecorp.net (Postfix) with ESMTP id CD33C83CFE5; Mon, 25 Jul 2022 03:24:18 +0000 (UTC) From: "Nickle Wang" To: devel@edk2.groups.io Cc: Abner Chang , Yang Atom , Nick Ramirez Subject: [edk2-devel] [edk2-staging][PATCH v3] edk2/RedfishPkg: Update Redfish Platform Config Protocol Date: Mon, 25 Jul 2022 11:24:17 +0800 Message-Id: <20220725032417.714-1-nickle.wang@hpe.com> MIME-Version: 1.0 X-Proofpoint-GUID: NN8iZTxE7VHQfq-dM9Znu9vYJjlz_SaI X-Proofpoint-ORIG-GUID: NN8iZTxE7VHQfq-dM9Znu9vYJjlz_SaI X-HPE-SCL: -1 Precedence: Bulk List-Unsubscribe: List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,nickle.wang@hpe.com X-Gm-Message-State: Vjk0pXMRi42CBzd5zqjiiLQVx1787277AA= Content-Transfer-Encoding: quoted-printable DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1658719468; bh=wzF74f9ShJiQoaHBMQnGZI1qCuVhi2hHOQ8hwt1860E=; h=Cc:Date:From:Reply-To:Subject:To; b=MYFk69LV7PDuIAlvqww6oiWExjU6/TVBjwr0P0awMPbGXr7VglJRFJqNKcPaM8IVM6M TKJ3OnyFgP3+G/QLfYx0a7j8wat3obRRajvpaouOMk9CdU5U6X/Km1ZH0/uzYM6VW7q71 qUz3rL++6ToBK+YTEE6eCjUJpUewv9E+IB8= X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1658719470537100003 Content-Type: text/plain; charset="utf-8" Update EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL and add array type of value support to EDKII_REDFISH_VALUE in order to support ordered list op-code in HII. Modify corresponding function to support new type of data structure. Signed-off-by: Nickle Wang Cc: Abner Chang Cc: Yang Atom Cc: Nick Ramirez Reviewed-by: Abner Chang --- .../Protocol/EdkIIRedfishPlatformConfig.h | 301 +- .../RedfishPlatformConfigDxe.c | 3087 ++++++++++------- .../RedfishPlatformConfigDxe.h | 128 +- .../RedfishPlatformConfigDxe.inf | 104 +- .../RedfishPlatformConfigImpl.c | 2528 +++++++------- .../RedfishPlatformConfigImpl.h | 571 +-- 6 files changed, 3638 insertions(+), 3081 deletions(-) diff --git a/RedfishPkg/Include/Protocol/EdkIIRedfishPlatformConfig.h b/Red= fishPkg/Include/Protocol/EdkIIRedfishPlatformConfig.h index 895b010227..bbbab90b03 100644 --- a/RedfishPkg/Include/Protocol/EdkIIRedfishPlatformConfig.h +++ b/RedfishPkg/Include/Protocol/EdkIIRedfishPlatformConfig.h @@ -1,147 +1,154 @@ -/** @file - This file defines the EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL interface. - - (C) Copyright 2021 Hewlett Packard Enterprise Development LP
- - SPDX-License-Identifier: BSD-2-Clause-Patent - -**/ - -#ifndef EDKII_REDFISH_PLATFORM_CONFIG_H_ -#define EDKII_REDFISH_PLATFORM_CONFIG_H_ - -typedef struct _EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL EDKII_REDFISH_PLATF= ORM_CONFIG_PROTOCOL; - -/** - Definition of EDKII_REDFISH_TYPE_VALUE - **/ -typedef union { - INT64 Integer; - BOOLEAN Boolean; - CHAR8 *Buffer; -} EDKII_REDFISH_TYPE_VALUE; - -/** - Definition of EDKII_REDFISH_VALUE_TYPES - **/ -typedef enum { - REDFISH_VALUE_TYPE_UNKNOWN =3D 0, - REDFISH_VALUE_TYPE_INTEGER, - REDFISH_VALUE_TYPE_BOOLEAN, - REDFISH_VALUE_TYPE_STRING, - REDFISH_VALUE_TYPE_MAX -} EDKII_REDFISH_VALUE_TYPES; - -/** - Definition of EDKII_REDFISH_VALUE - **/ -typedef struct { - EDKII_REDFISH_VALUE_TYPES Type; - EDKII_REDFISH_TYPE_VALUE Value; -} EDKII_REDFISH_VALUE; - -/** - Get Redfish value with the given Schema and Configure Language. - - @param[in] This Pointer to EDKII_REDFISH_PLATFORM_CONFI= G_PROTOCOL instance. - @param[in] Schema The Redfish schema to query. - @param[in] Version The Redfish version to query. - @param[in] ConfigureLang The target value which match this confi= gure Language. - @param[out] Value The returned value. - - @retval EFI_SUCCESS Value is returned successfully. - @retval Others Some error happened. - -**/ -typedef -EFI_STATUS -(EFIAPI *EDKII_REDFISH_PLATFORM_CONFIG_GET_VALUE) ( - IN EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL *This, - IN CHAR8 *Schema, - IN CHAR8 *Version, - IN EFI_STRING ConfigureLang, - OUT EDKII_REDFISH_VALUE *Value - ); - -/** - Set Redfish value with the given Schema and Configure Language. - - @param[in] This Pointer to EDKII_REDFISH_PLATFORM_CONFI= G_PROTOCOL instance. - @param[in] Schema The Redfish schema to query. - @param[in] Version The Redfish version to query. - @param[in] ConfigureLang The target value which match this confi= gure Language. - @param[in] Value The value to set. - - @retval EFI_SUCCESS Value is returned successfully. - @retval Others Some error happened. - -**/ -typedef -EFI_STATUS -(EFIAPI *EDKII_REDFISH_PLATFORM_CONFIG_SET_VALUE) ( - IN EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL *This, - IN CHAR8 *Schema, - IN CHAR8 *Version, - IN EFI_STRING ConfigureLang, - IN EDKII_REDFISH_VALUE Value - ); - -/** - Get the list of Configure Language from platform configuration by the gi= ven Schema and Pattern. - - @param[in] This Pointer to EDKII_REDFISH_PLATFORM_CONFI= G_PROTOCOL instance. - @param[in] Schema The Redfish schema to query. - @param[in] Version The Redfish version to query. - @param[in] Pattern The target Configure Language pattern. - @param[out] ConfigureLangList The list of Configure Language. - @param[out] Count The number of Configure Language in Con= figureLangList. - - @retval EFI_SUCCESS ConfigureLangList is returned successfu= lly. - @retval Others Some error happened. - -**/ -typedef -EFI_STATUS -(EFIAPI *EDKII_REDFISH_PLATFORM_CONFIG_GET_CONFIG_LANG) ( - IN EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL *This, - IN CHAR8 *Schema, - IN CHAR8 *Version, - IN EFI_STRING Pattern, - OUT EFI_STRING **ConfigureLangList, - OUT UINTN *Count - ); - - -/** - Get the list of supported Redfish schema from platform configuration on = the give HII handle. - - @param[in] This Pointer to EDKII_REDFISH_PLATFORM_CONFI= G_PROTOCOL instance. - @param[in] HiiHandle The target handle to search. If handle = is NULL, - this function returns all schema from H= II database. - @param[out] SupportedSchema The supported schema list which is sepa= rated by ';'. - For example: "x-uefi-redfish-Memory.v1_= 7_1;x-uefi-redfish-Boot.v1_0_1" - The SupportedSchema is allocated by the= callee. It's caller's - responsibility to free this buffer usin= g FreePool(). - - @retval EFI_SUCCESS Schema is returned successfully. - @retval Others Some error happened. - -**/ -typedef -EFI_STATUS -(EFIAPI *EDKII_REDFISH_PLATFORM_CONFIG_GET_SUPPORTED_SCHEMA) ( - IN EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL *This, - IN EFI_HII_HANDLE HiiHandle, OPTION= AL - OUT CHAR8 **SupportedSchema - ); - -struct _EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL { - EDKII_REDFISH_PLATFORM_CONFIG_GET_VALUE GetValue; - EDKII_REDFISH_PLATFORM_CONFIG_SET_VALUE SetValue; - EDKII_REDFISH_PLATFORM_CONFIG_GET_CONFIG_LANG GetConfigureLang; - EDKII_REDFISH_PLATFORM_CONFIG_GET_SUPPORTED_SCHEMA GetSupportedSchema; -}; - -extern EFI_GUID gEdkIIRedfishPlatformConfigProtocolGuid; - -#endif +/** @file + This file defines the EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL interface. + + (C) Copyright 2021-2022 Hewlett Packard Enterprise Development LP
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef EDKII_REDFISH_PLATFORM_CONFIG_H_ +#define EDKII_REDFISH_PLATFORM_CONFIG_H_ + +typedef struct _EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL EDKII_REDFISH_PLATF= ORM_CONFIG_PROTOCOL; + +/** + Definition of EDKII_REDFISH_TYPE_VALUE + **/ +typedef union { + INT64 Integer; + BOOLEAN Boolean; + CHAR8 *Buffer; + CHAR8 **StringArray; + INT64 *IntegerArray; + BOOLEAN *BooleanArray; +} EDKII_REDFISH_TYPE_VALUE; + +/** + Definition of EDKII_REDFISH_VALUE_TYPES + **/ +typedef enum { + REDFISH_VALUE_TYPE_UNKNOWN =3D 0, + REDFISH_VALUE_TYPE_INTEGER, + REDFISH_VALUE_TYPE_BOOLEAN, + REDFISH_VALUE_TYPE_STRING, + REDFISH_VALUE_TYPE_STRING_ARRAY, + REDFISH_VALUE_TYPE_INTEGER_ARRAY, + REDFISH_VALUE_TYPE_BOOLEAN_ARRAY, + REDFISH_VALUE_TYPE_MAX +} EDKII_REDFISH_VALUE_TYPES; + +/** + Definition of EDKII_REDFISH_VALUE + **/ +typedef struct { + EDKII_REDFISH_VALUE_TYPES Type; + EDKII_REDFISH_TYPE_VALUE Value; + UINTN ArrayCount; +} EDKII_REDFISH_VALUE; + +/** + Get Redfish value with the given Schema and Configure Language. + + @param[in] This Pointer to EDKII_REDFISH_PLATFORM_CONFI= G_PROTOCOL instance. + @param[in] Schema The Redfish schema to query. + @param[in] Version The Redfish version to query. + @param[in] ConfigureLang The target value which match this confi= gure Language. + @param[out] Value The returned value. + + @retval EFI_SUCCESS Value is returned successfully. + @retval Others Some error happened. + +**/ +typedef +EFI_STATUS +(EFIAPI *EDKII_REDFISH_PLATFORM_CONFIG_GET_VALUE) ( + IN EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL *This, + IN CHAR8 *Schema, + IN CHAR8 *Version, + IN EFI_STRING ConfigureLang, + OUT EDKII_REDFISH_VALUE *Value + ); + +/** + Set Redfish value with the given Schema and Configure Language. + + @param[in] This Pointer to EDKII_REDFISH_PLATFORM_CONFI= G_PROTOCOL instance. + @param[in] Schema The Redfish schema to query. + @param[in] Version The Redfish version to query. + @param[in] ConfigureLang The target value which match this confi= gure Language. + @param[in] Value The value to set. + + @retval EFI_SUCCESS Value is returned successfully. + @retval Others Some error happened. + +**/ +typedef +EFI_STATUS +(EFIAPI *EDKII_REDFISH_PLATFORM_CONFIG_SET_VALUE) ( + IN EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL *This, + IN CHAR8 *Schema, + IN CHAR8 *Version, + IN EFI_STRING ConfigureLang, + IN EDKII_REDFISH_VALUE Value + ); + +/** + Get the list of Configure Language from platform configuration by the gi= ven Schema and RegexPattern. + + @param[in] This Pointer to EDKII_REDFISH_PLATFORM_CONFI= G_PROTOCOL instance. + @param[in] Schema The Redfish schema to query. + @param[in] Version The Redfish version to query. + @param[in] RegexPattern The target Configure Language pattern. = This is used for regular expression matching. + @param[out] ConfigureLangList The list of Configure Language. + @param[out] Count The number of Configure Language in Con= figureLangList. + + @retval EFI_SUCCESS ConfigureLangList is returned successfu= lly. + @retval Others Some error happened. + +**/ +typedef +EFI_STATUS +(EFIAPI *EDKII_REDFISH_PLATFORM_CONFIG_GET_CONFIG_LANG) ( + IN EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL *This, + IN CHAR8 *Schema, + IN CHAR8 *Version, + IN EFI_STRING RegexPattern, + OUT EFI_STRING **ConfigureLangList, + OUT UINTN *Count + ); + + +/** + Get the list of supported Redfish schema from platform configuration on = the give HII handle. + + @param[in] This Pointer to EDKII_REDFISH_PLATFORM_CONFI= G_PROTOCOL instance. + @param[in] HiiHandle The target handle to search. If handle = is NULL, + this function returns all schema from H= II database. + @param[out] SupportedSchema The supported schema list which is sepa= rated by ';'. + For example: "x-uefi-redfish-Memory.v1_= 7_1;x-uefi-redfish-Boot.v1_0_1" + The SupportedSchema is allocated by the= callee. It's caller's + responsibility to free this buffer usin= g FreePool(). + + @retval EFI_SUCCESS Schema is returned successfully. + @retval Others Some error happened. + +**/ +typedef +EFI_STATUS +(EFIAPI *EDKII_REDFISH_PLATFORM_CONFIG_GET_SUPPORTED_SCHEMA) ( + IN EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL *This, + IN EFI_HII_HANDLE HiiHandle, OPTION= AL + OUT CHAR8 **SupportedSchema + ); + +struct _EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL { + EDKII_REDFISH_PLATFORM_CONFIG_GET_VALUE GetValue; + EDKII_REDFISH_PLATFORM_CONFIG_SET_VALUE SetValue; + EDKII_REDFISH_PLATFORM_CONFIG_GET_CONFIG_LANG GetConfigureLang; + EDKII_REDFISH_PLATFORM_CONFIG_GET_SUPPORTED_SCHEMA GetSupportedSchema; +}; + +extern EFI_GUID gEdkIIRedfishPlatformConfigProtocolGuid; + +#endif diff --git a/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.c= b/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.c index 67818cccd2..971035f27d 100644 --- a/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.c +++ b/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.c @@ -1,1304 +1,1783 @@ -/** @file - - The implementation of EDKII Redfidh Platform Config Protocol. - - (C) Copyright 2021 Hewlett Packard Enterprise Development LP
- - SPDX-License-Identifier: BSD-2-Clause-Patent - -**/ - -#include "RedfishPlatformConfigDxe.h" -#include "RedfishPlatformConfigImpl.h" - -REDFISH_PLATFORM_CONFIG_PRIVATE *mRedfishPlatformConfigPrivate =3D NULL; - -/** - Compare two value in HII statement format. - - @param[in] Value1 Firt value to compare. - @param[in] Value2 Second value to be compared. - - @retval UINTN 0 is retuned when two values are equal. - 1 is returned when first value is greater than sec= ond value. - -1 is returned when second value is greater than f= irst value. - -**/ -UINTN -CompareHiiStatementValue ( - IN HII_STATEMENT_VALUE *Value1, - IN HII_STATEMENT_VALUE *Value2 - ) -{ - INTN Result; - UINT64 Data1; - UINT64 Data2; - - if (Value1 =3D=3D NULL || Value2 =3D=3D NULL) { - return 0xFF; - } - - switch (Value1->Type) { - case EFI_IFR_TYPE_NUM_SIZE_8: - Data1 =3D Value1->Value.u8; - break; - case EFI_IFR_TYPE_NUM_SIZE_16: - Data1 =3D Value1->Value.u16; - break; - case EFI_IFR_TYPE_NUM_SIZE_32: - Data1 =3D Value1->Value.u32; - break; - case EFI_IFR_TYPE_NUM_SIZE_64: - Data1 =3D Value1->Value.u64; - break; - case EFI_IFR_TYPE_BOOLEAN: - Data1 =3D (Value1->Value.b ? 1 : 0); - break; - default: - return 0xFF; - } - - switch (Value2->Type) { - case EFI_IFR_TYPE_NUM_SIZE_8: - Data2 =3D Value2->Value.u8; - break; - case EFI_IFR_TYPE_NUM_SIZE_16: - Data2 =3D Value2->Value.u16; - break; - case EFI_IFR_TYPE_NUM_SIZE_32: - Data2 =3D Value2->Value.u32; - break; - case EFI_IFR_TYPE_NUM_SIZE_64: - Data2 =3D Value2->Value.u64; - break; - case EFI_IFR_TYPE_BOOLEAN: - Data2 =3D (Value2->Value.b ? 1 : 0); - break; - default: - return 0xFF; - } - - Result =3D (Data1 =3D=3D Data2 ? 0 : (Data1 > Data2 ? 1 : -1)); - - return Result; -} - -/** - Convert HII value to the string in HII one-of opcode. - - @param[in] Statement Statement private instance - - @retval EFI_STRING_ID The string ID in HII database. - 0 is returned when something goes wrong. - -**/ -EFI_STRING_ID -HiiValueToOneOfOptionStringId ( - IN REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE *Statement - ) -{ - LIST_ENTRY *Link; - HII_QUESTION_OPTION *Option; - - if (Statement->HiiStatement->Operand !=3D EFI_IFR_ONE_OF_OP) { - return 0; - } - - if (IsListEmpty (&Statement->HiiStatement->OptionListHead)) { - return 0; - } - - Link =3D GetFirstNode (&Statement->HiiStatement->OptionListHead); - while (!IsNull (&Statement->HiiStatement->OptionListHead, Link)) { - Option =3D HII_QUESTION_OPTION_FROM_LINK (Link); - - if (CompareHiiStatementValue (&Statement->HiiStatement->Value, &Option= ->Value) =3D=3D 0) { - return Option->Text; - } - - Link =3D GetNextNode (&Statement->HiiStatement->OptionListHead, Link); - } - - return 0; -} - -/** - Convert HII string to the value in HII one-of opcode. - - @param[in] Statement Statement private instance - @param[in] Schema Schema string - @param[in] HiiString Input string - @param[out] Value Value returned - - @retval EFI_SUCCESS HII value is returned successfully. - @retval Others Errors occur - -**/ -EFI_STATUS -HiiStringToOneOfOptionValue ( - IN REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE *Statement, - IN CHAR8 *Schema, - IN EFI_STRING HiiString, - OUT HII_STATEMENT_VALUE *Value - ) -{ - LIST_ENTRY *Link; - HII_QUESTION_OPTION *Option; - EFI_STRING TmpString; - BOOLEAN Found; - - if (Statement =3D=3D NULL || IS_EMPTY_STRING (HiiString) || Value =3D=3D= NULL) { - return EFI_INVALID_PARAMETER; - } - - if (Statement->HiiStatement->Operand !=3D EFI_IFR_ONE_OF_OP) { - return EFI_UNSUPPORTED; - } - - if (IsListEmpty (&Statement->HiiStatement->OptionListHead)) { - return EFI_NOT_FOUND; - } - - Found =3D FALSE; - Link =3D GetFirstNode (&Statement->HiiStatement->OptionListHead); - while (!IsNull (&Statement->HiiStatement->OptionListHead, Link)) { - Option =3D HII_QUESTION_OPTION_FROM_LINK (Link); - - TmpString =3D HiiGetRedfishString (Statement->ParentForm->ParentFormse= t->HiiHandle, Schema, Option->Text); - if (TmpString !=3D NULL) { - if (StrCmp (TmpString, HiiString) =3D=3D 0) { - CopyMem (Value, &Option->Value, sizeof (HII_STATEMENT_VALUE)); - Found =3D TRUE; - } - FreePool (TmpString); - } - - if (Found) { - return EFI_SUCCESS; - } - - Link =3D GetNextNode (&Statement->HiiStatement->OptionListHead, Link); - } - - return EFI_NOT_FOUND; -} - -/** - Convert HII value to numeric value in Redfish format. - - @param[in] Value Value to be converted. - @param[out] RedfishValue Value in Redfish format. - - @retval EFI_SUCCESS Redfish value is returned successfully. - @retval Others Errors occur - -**/ -EFI_STATUS -HiiValueToRedfishNumeric ( - IN HII_STATEMENT_VALUE *Value, - OUT EDKII_REDFISH_VALUE *RedfishValue - ) -{ - if (Value =3D=3D NULL || RedfishValue =3D=3D NULL) { - return EFI_INVALID_PARAMETER; - } - - switch (Value->Type) { - case EFI_IFR_TYPE_NUM_SIZE_8: - RedfishValue->Type =3D REDFISH_VALUE_TYPE_INTEGER; - RedfishValue->Value.Integer =3D (INT64)Value->Value.u8; - break; - case EFI_IFR_TYPE_NUM_SIZE_16: - RedfishValue->Type =3D REDFISH_VALUE_TYPE_INTEGER; - RedfishValue->Value.Integer =3D (INT64)Value->Value.u16; - break; - case EFI_IFR_TYPE_NUM_SIZE_32: - RedfishValue->Type =3D REDFISH_VALUE_TYPE_INTEGER; - RedfishValue->Value.Integer =3D (INT64)Value->Value.u32; - break; - case EFI_IFR_TYPE_NUM_SIZE_64: - RedfishValue->Type =3D REDFISH_VALUE_TYPE_INTEGER; - RedfishValue->Value.Integer =3D (INT64)Value->Value.u64; - break; - case EFI_IFR_TYPE_BOOLEAN: - RedfishValue->Type =3D REDFISH_VALUE_TYPE_BOOLEAN; - RedfishValue->Value.Boolean =3D Value->Value.b; - break; - default: - RedfishValue->Type =3D REDFISH_VALUE_TYPE_UNKNOWN; - break; - } - - return EFI_SUCCESS; -} - -/** - Convert numeric value in Redfish format to HII value. - - @param[in] RedfishValue Value in Redfish format to be converted. - @param[out] Value HII value returned. - - @retval EFI_SUCCESS HII value is returned successfully. - @retval Others Errors occur - -**/ -EFI_STATUS -RedfishNumericToHiiValue ( - IN EDKII_REDFISH_VALUE *RedfishValue, - OUT HII_STATEMENT_VALUE *Value - ) -{ - if (Value =3D=3D NULL || RedfishValue =3D=3D NULL) { - return EFI_INVALID_PARAMETER; - } - - switch (RedfishValue->Type) { - case REDFISH_VALUE_TYPE_INTEGER: - Value->Type =3D EFI_IFR_TYPE_NUM_SIZE_64; - Value->Value.u64 =3D (UINT64)RedfishValue->Value.Integer; - break; - case REDFISH_VALUE_TYPE_BOOLEAN: - Value->Type =3D EFI_IFR_TYPE_BOOLEAN; - Value->Value.b =3D RedfishValue->Value.Boolean; - break; - default: - Value->Type =3D EFI_IFR_TYPE_UNDEFINED; - break; - } - - return EFI_SUCCESS; -} - -/** - Return the full Redfish schema string from the given Schema and Version. - - Returned schema string is: Schema + '.' + Version - - @param[in] Schema Schema string - @param[in] Version Schema version string - - @retval CHAR8 * Schema string. NULL when errors occur. - -**/ -CHAR8 * -GetFullSchemaString ( - IN CHAR8 *Schema, - IN CHAR8 *Version - ) -{ - UINTN Size; - CHAR8 *FullName; - - if (IS_EMPTY_STRING (Schema) || IS_EMPTY_STRING (Version)) { - return NULL; - } - - Size =3D AsciiStrSize(CONFIGURE_LANGUAGE_PREFIX) + AsciiStrSize (Schema)= + AsciiStrSize (Version); - - FullName =3D AllocatePool (Size); - if (FullName =3D=3D NULL) { - DEBUG ((DEBUG_ERROR, "%a, out-of-resource\n", __FUNCTION__)); - return NULL; - } - - AsciiSPrint (FullName, Size, "%a%a.%a", CONFIGURE_LANGUAGE_PREFIX, Schem= a, Version); - - return FullName; -} - -/** - Common implementation to get statement private instance. - - @param[in] RedfishPlatformConfigPrivate Private instance. - @param[in] Schema Redfish schema string. - @param[in] ConfigureLang Configure language that refe= rs to this statement. - @param[out] Statement Statement instance - - @retval EFI_SUCCESS HII value is returned successfully. - @retval Others Errors occur - -**/ -EFI_STATUS -RedfishPlatformConfigGetStatementCommon ( - IN REDFISH_PLATFORM_CONFIG_PRIVATE *RedfishPlatformConfig= Private, - IN CHAR8 *Schema, - IN EFI_STRING ConfigureLang, - OUT REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE **Statement - ) -{ - EFI_STATUS Status; - REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE *TargetStatement; - - if (RedfishPlatformConfigPrivate =3D=3D NULL || IS_EMPTY_STRING (Schema)= || IS_EMPTY_STRING (ConfigureLang) || Statement =3D=3D NULL) { - return EFI_INVALID_PARAMETER; - } - - *Statement =3D NULL; - - Status =3D ProcessPendingList (&RedfishPlatformConfigPrivate->FormsetLis= t, &RedfishPlatformConfigPrivate->PendingList); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "%a, ProcessPendingList failure: %r\n", __FUNCTIO= N__, Status)); - return Status; - } - - TargetStatement =3D GetStatementPrivateByConfigureLang (&RedfishPlatform= ConfigPrivate->FormsetList, Schema, ConfigureLang); - if (TargetStatement =3D=3D NULL) { - DEBUG ((DEBUG_ERROR, "%a, No match HII statement is found by the given= %s in schema %a\n", __FUNCTION__, ConfigureLang, Schema)); - return EFI_NOT_FOUND; - } - - // - // Find current HII question value. - // - Status =3D GetQuestionValue ( - TargetStatement->ParentForm->ParentFormset->HiiFormSet, - TargetStatement->ParentForm->HiiForm, - TargetStatement->HiiStatement, - GetSetValueWithHiiDriver - ); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "%a, failed to get question current value: %r\n",= __FUNCTION__, Status)); - return Status; - } - - - if (TargetStatement->HiiStatement->Value.Type =3D=3D EFI_IFR_TYPE_UNDEFI= NED) { - return EFI_DEVICE_ERROR; - } - - // - // Return Value. - // - *Statement =3D TargetStatement; - - return EFI_SUCCESS; -} - -/** - Get Redfish value with the given Schema and Configure Language. - - @param[in] This Pointer to EDKII_REDFISH_PLATFORM_CONFI= G_PROTOCOL instance. - @param[in] Schema The Redfish schema to query. - @param[in] Version The Redfish version to query. - @param[in] ConfigureLang The target value which match this confi= gure Language. - @param[out] Value The returned value. - - @retval EFI_SUCCESS Value is returned successfully. - @retval Others Some error happened. - -**/ -EFI_STATUS -EFIAPI -RedfishPlatformConfigProtocolGetValue ( - IN EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL *This, - IN CHAR8 *Schema, - IN CHAR8 *Version, - IN EFI_STRING ConfigureLang, - OUT EDKII_REDFISH_VALUE *Value - ) -{ - EFI_STATUS Status; - REDFISH_PLATFORM_CONFIG_PRIVATE *RedfishPlatformConfigPrivate; - REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE *TargetStatement; - EFI_STRING_ID StringId; - CHAR8 *FullSchema; - EFI_STRING HiiString; - UINTN Size; - - if (This =3D=3D NULL || IS_EMPTY_STRING (Schema) || IS_EMPTY_STRING (Ver= sion) || IS_EMPTY_STRING (ConfigureLang) || Value =3D=3D NULL) { - return EFI_INVALID_PARAMETER; - } - - RedfishPlatformConfigPrivate =3D REDFISH_PLATFORM_CONFIG_PRIVATE_FROM_TH= IS (This); - Value->Type =3D REDFISH_VALUE_TYPE_UNKNOWN; - FullSchema =3D NULL; - HiiString =3D NULL; - - FullSchema =3D GetFullSchemaString (Schema, Version); - if (FullSchema =3D=3D NULL) { - return EFI_OUT_OF_RESOURCES; - } - - Status =3D RedfishPlatformConfigGetStatementCommon (RedfishPlatformConfi= gPrivate, FullSchema, ConfigureLang, &TargetStatement); - if (EFI_ERROR (Status)) { - goto RELEASE_RESOURCE; - } - - switch (TargetStatement->HiiStatement->Operand) { - case EFI_IFR_ONE_OF_OP: - StringId =3D HiiValueToOneOfOptionStringId (TargetStatement); - if (StringId =3D=3D 0) { - ASSERT (FALSE); - Status =3D EFI_DEVICE_ERROR; - goto RELEASE_RESOURCE; - } - - HiiString =3D HiiGetRedfishString (TargetStatement->ParentForm->Pare= ntFormset->HiiHandle, FullSchema, StringId); - if (HiiString =3D=3D NULL) { - DEBUG ((DEBUG_ERROR, "%a, Can not find string ID: 0x%x with %a\n",= __FUNCTION__, StringId, FullSchema)); - Status =3D EFI_NOT_FOUND; - goto RELEASE_RESOURCE; - } - - Size =3D StrLen (HiiString) + 1; - Value->Value.Buffer =3D AllocatePool (Size); - if (Value->Value.Buffer =3D=3D NULL) { - Status =3D EFI_OUT_OF_RESOURCES; - goto RELEASE_RESOURCE; - } - - UnicodeStrToAsciiStrS (HiiString, Value->Value.Buffer, Size); - Value->Type =3D REDFISH_VALUE_TYPE_STRING; - - break; - case EFI_IFR_STRING_OP: - if (TargetStatement->HiiStatement->Value.Type !=3D EFI_IFR_TYPE_STRI= NG) { - ASSERT (FALSE); - Status =3D EFI_DEVICE_ERROR; - goto RELEASE_RESOURCE; - } - - Value->Type =3D REDFISH_VALUE_TYPE_STRING; - Value->Value.Buffer =3D AllocateCopyPool (StrSize ((CHAR16 *)TargetS= tatement->HiiStatement->Value.Buffer), TargetStatement->HiiStatement->Value= .Buffer); - if (Value->Value.Buffer =3D=3D NULL) { - Status =3D EFI_OUT_OF_RESOURCES; - goto RELEASE_RESOURCE; - } - break; - case EFI_IFR_CHECKBOX_OP: - case EFI_IFR_NUMERIC_OP: - Status =3D HiiValueToRedfishNumeric (&TargetStatement->HiiStatement-= >Value, Value); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "%a, failed to convert HII value to Redfish v= alue: %r\n", __FUNCTION__, Status)); - goto RELEASE_RESOURCE; - } - break; - default: - DEBUG ((DEBUG_ERROR, "%a, catch unsupported type: 0x%x! Please conta= ct with author if we need to support this type.\n", __FUNCTION__, TargetSta= tement->HiiStatement->Operand)); - ASSERT (FALSE); - Status =3D EFI_UNSUPPORTED; - goto RELEASE_RESOURCE; - } - -RELEASE_RESOURCE: - - if (FullSchema !=3D NULL) { - FreePool (FullSchema); - } - - if (HiiString !=3D NULL) { - FreePool (HiiString); - } - - return Status; -} - -/** - Function to save question value into HII database. - - @param[in] HiiFormset HII form-set instance - @param[in] HiiForm HII form instance - @param[in] HiiStatement HII statement that keeps new value. - @param[in] Value New value to applyu. - - @retval EFI_SUCCESS HII value is returned successfully. - @retval Others Errors occur - -**/ -EFI_STATUS -RedfishPlatformConfigSaveQuestionValue ( - IN HII_FORMSET *HiiFormset, - IN HII_FORM *HiiForm, - IN HII_STATEMENT *HiiStatement, - IN HII_STATEMENT_VALUE *Value - ) -{ - EFI_STATUS Status; - - if (HiiFormset =3D=3D NULL || HiiForm =3D=3D NULL || HiiStatement =3D=3D= NULL || Value =3D=3D NULL) { - return EFI_INVALID_PARAMETER; - } - - Status =3D SetQuestionValue ( - HiiFormset, - HiiForm, - HiiStatement, - Value - ); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "%a, failed to set question value: %r\n", __FUNCT= ION__, Status)); - return Status; - } - - Status =3D SubmitForm (HiiFormset, HiiForm); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "%a, failed to submit form: %r\n", __FUNCTION__, = Status)); - return Status; - } - - return EFI_SUCCESS; -} - -/** - Common implementation to set statement private instance. - - @param[in] RedfishPlatformConfigPrivate Private instance. - @param[in] Schema Redfish schema string. - @param[in] ConfigureLang Configure language that refe= rs to this statement. - @param[in] Statement Statement instance - - @retval EFI_SUCCESS HII value is returned successfully. - @retval Others Errors occur - -**/ -EFI_STATUS -RedfishPlatformConfigSetStatementCommon ( - IN REDFISH_PLATFORM_CONFIG_PRIVATE *RedfishPlatformConfigPrivate, - IN CHAR8 *Schema, - IN EFI_STRING ConfigureLang, - IN HII_STATEMENT_VALUE *StatementValue - ) -{ - EFI_STATUS Status; - REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE *TargetStatement; - EFI_STRING TempBuffer; - - if (RedfishPlatformConfigPrivate =3D=3D NULL || IS_EMPTY_STRING (Schema)= || IS_EMPTY_STRING (ConfigureLang) || StatementValue =3D=3D NULL) { - return EFI_INVALID_PARAMETER; - } - - TempBuffer =3D NULL; - - Status =3D ProcessPendingList (&RedfishPlatformConfigPrivate->FormsetLis= t, &RedfishPlatformConfigPrivate->PendingList); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "%a, ProcessPendingList failure: %r\n", __FUNCTIO= N__, Status)); - return Status; - } - - TargetStatement =3D GetStatementPrivateByConfigureLang (&RedfishPlatform= ConfigPrivate->FormsetList, Schema, ConfigureLang); - if (TargetStatement =3D=3D NULL) { - DEBUG ((DEBUG_ERROR, "%a, No match HII statement is found by the given= %s in schema %a\n", __FUNCTION__, ConfigureLang, Schema)); - return EFI_NOT_FOUND; - } - - if (StatementValue->Type !=3D TargetStatement->HiiStatement->Value.Type)= { - // - // We treat one-of type as string in Redfish. But one-of statement is = not - // in string format from HII point of view. Do a patch here. - // - if (TargetStatement->HiiStatement->Operand =3D=3D EFI_IFR_ONE_OF_OP &&= StatementValue->Type =3D=3D EFI_IFR_TYPE_STRING) { - TempBuffer =3D AllocatePool (StatementValue->BufferLen * sizeof (CHA= R16)); - if (TempBuffer =3D=3D NULL) { - return EFI_OUT_OF_RESOURCES; - } - - AsciiStrToUnicodeStrS (StatementValue->Buffer, TempBuffer, Statement= Value->BufferLen); - FreePool (StatementValue->Buffer); - StatementValue->Buffer =3D NULL; - StatementValue->BufferLen =3D 0; - - Status =3D HiiStringToOneOfOptionValue (TargetStatement, Schema, Tem= pBuffer, StatementValue); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "%a, failed to find option value by the given= %s\n", __FUNCTION__, TempBuffer)); - FreePool (TempBuffer); - return EFI_NOT_FOUND; - } - - FreePool (TempBuffer); - } else if (TargetStatement->HiiStatement->Operand =3D=3D EFI_IFR_NUMER= IC_OP && StatementValue->Type =3D=3D EFI_IFR_TYPE_NUM_SIZE_64) { - // - // Redfish only has numeric value type and it does not care about th= e value size. - // Do a patch here so we have proper value size applied. - // - StatementValue->Type =3D TargetStatement->HiiStatement->Value.Type; - } else { - DEBUG ((DEBUG_ERROR, "%a, catch value type mismatch! input type: 0x%= x but target value type: 0x%x\n", __FUNCTION__, StatementValue->Type, Targe= tStatement->HiiStatement->Value.Type)); - ASSERT (FALSE); - } - } - - Status =3D RedfishPlatformConfigSaveQuestionValue ( - TargetStatement->ParentForm->ParentFormset->HiiFormSet, - TargetStatement->ParentForm->HiiForm, - TargetStatement->HiiStatement, - StatementValue - ); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "%a, failed to save question value: %r\n", __FUNC= TION__, Status)); - return Status; - } - - return EFI_SUCCESS; -} - -/** - Set Redfish value with the given Schema and Configure Language. - - @param[in] This Pointer to EDKII_REDFISH_PLATFORM_CONFI= G_PROTOCOL instance. - @param[in] Schema The Redfish schema to query. - @param[in] Version The Redfish version to query. - @param[in] ConfigureLang The target value which match this confi= gure Language. - @param[in] Value The value to set. - - @retval EFI_SUCCESS Value is returned successfully. - @retval Others Some error happened. - -**/ -EFI_STATUS -EFIAPI -RedfishPlatformConfigProtocolSetValue ( - IN EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL *This, - IN CHAR8 *Schema, - IN CHAR8 *Version, - IN EFI_STRING ConfigureLang, - IN EDKII_REDFISH_VALUE Value - ) -{ - EFI_STATUS Status; - REDFISH_PLATFORM_CONFIG_PRIVATE *RedfishPlatformConfigPrivate; - CHAR8 *FullSchema; - HII_STATEMENT_VALUE NewValue; - - if (This =3D=3D NULL || IS_EMPTY_STRING (Schema) || IS_EMPTY_STRING (Ver= sion) || IS_EMPTY_STRING (ConfigureLang)) { - return EFI_INVALID_PARAMETER; - } - - if (Value.Type =3D=3D REDFISH_VALUE_TYPE_UNKNOWN || Value.Type >=3D REDF= ISH_VALUE_TYPE_MAX) { - return EFI_INVALID_PARAMETER; - } - - RedfishPlatformConfigPrivate =3D REDFISH_PLATFORM_CONFIG_PRIVATE_FROM_TH= IS (This); - FullSchema =3D NULL; - - FullSchema =3D GetFullSchemaString (Schema, Version); - if (FullSchema =3D=3D NULL) { - return EFI_OUT_OF_RESOURCES; - } - - ZeroMem (&NewValue, sizeof (HII_STATEMENT_VALUE)); - - switch (Value.Type) { - case REDFISH_VALUE_TYPE_INTEGER: - case REDFISH_VALUE_TYPE_BOOLEAN: - Status =3D RedfishNumericToHiiValue (&Value, &NewValue); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "%a, failed to convert Redfish value to Hii v= alue: %r\n", __FUNCTION__, Status)); - goto RELEASE_RESOURCE; - } - break; - case REDFISH_VALUE_TYPE_STRING: - NewValue.Type =3D EFI_IFR_TYPE_STRING; - NewValue.BufferLen =3D (UINT16)AsciiStrSize (Value.Value.Buffer); - NewValue.Buffer =3D AllocateCopyPool (NewValue.BufferLen, Value.Valu= e.Buffer); - if (NewValue.Buffer =3D=3D NULL) { - Status =3D EFI_OUT_OF_RESOURCES; - goto RELEASE_RESOURCE; - } - break; - default: - ASSERT (FALSE); - break; - } - - Status =3D RedfishPlatformConfigSetStatementCommon (RedfishPlatformConfi= gPrivate, FullSchema, ConfigureLang, &NewValue); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "%a, failed to set value to statement: %r\n", __F= UNCTION__, Status)); - } - -RELEASE_RESOURCE: - - if (FullSchema !=3D NULL) { - FreePool (FullSchema); - } - - return Status; -} - -/** - Get the list of Configure Language from platform configuration by the gi= ven Schema and Pattern. - - @param[in] This Pointer to EDKII_REDFISH_PLATFORM_CONFI= G_PROTOCOL instance. - @param[in] Schema The Redfish schema to query. - @param[in] Version The Redfish version to query. - @param[in] Pattern The target Configure Language pattern. - @param[out] ConfigureLangList The list of Configure Language. - @param[out] Count The number of Configure Language in Con= figureLangList. - - @retval EFI_SUCCESS ConfigureLangList is returned successfu= lly. - @retval Others Some error happened. - -**/ -EFI_STATUS -EFIAPI -RedfishPlatformConfigProtocolGetConfigureLang ( - IN EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL *This, - IN CHAR8 *Schema, - IN CHAR8 *Version, - IN EFI_STRING Pattern, - OUT EFI_STRING **ConfigureLangList, - OUT UINTN *Count - ) -{ - REDFISH_PLATFORM_CONFIG_PRIVATE *RedfishPlatformConfigPr= ivate; - EFI_STATUS Status; - REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_LIST StatementList; - REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_REF *StatementRef; - LIST_ENTRY *NextLink; - EFI_STRING TmpString; - EFI_STRING *TmpConfigureLangList; - UINTN Index; - CHAR8 *FullSchema; - - if (This =3D=3D NULL || IS_EMPTY_STRING (Schema) || IS_EMPTY_STRING (Ver= sion) || Count =3D=3D NULL || ConfigureLangList =3D=3D NULL || IS_EMPTY_STR= ING (Pattern)) { - return EFI_INVALID_PARAMETER; - } - - *Count =3D 0; - *ConfigureLangList =3D NULL; - FullSchema =3D NULL; - RedfishPlatformConfigPrivate =3D REDFISH_PLATFORM_CONFIG_PRIVATE_FROM_TH= IS (This); - - Status =3D ProcessPendingList (&RedfishPlatformConfigPrivate->FormsetLis= t, &RedfishPlatformConfigPrivate->PendingList); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "%a, ProcessPendingList failure: %r\n", __FUNCTIO= N__, Status)); - return Status; - } - - FullSchema =3D GetFullSchemaString (Schema, Version); - if (FullSchema =3D=3D NULL) { - return EFI_OUT_OF_RESOURCES; - } - - Status =3D GetStatementPrivateByConfigureLangRegex ( - RedfishPlatformConfigPrivate->RegularExpressionProtocol, - &RedfishPlatformConfigPrivate->FormsetList, - FullSchema, - Pattern, - &StatementList - ); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "%a, GetStatementPrivateByConfigureLangRegex fail= ure: %r\n", __FUNCTION__, Status)); - goto RELEASE_RESOURCE; - } - - if (!IsListEmpty (&StatementList.StatementList)) { - - TmpConfigureLangList =3D AllocateZeroPool (sizeof (CHAR16 *) * Stateme= ntList.Count); - if (TmpConfigureLangList =3D=3D NULL) { - Status =3D EFI_OUT_OF_RESOURCES; - goto RELEASE_RESOURCE; - } - - Index =3D 0; - NextLink =3D GetFirstNode (&StatementList.StatementList); - while (!IsNull (&StatementList.StatementList, NextLink)) { - StatementRef =3D REDFISH_PLATFORM_CONFIG_STATEMENT_REF_FROM_LINK (Ne= xtLink); - NextLink =3D GetNextNode (&StatementList.StatementList, NextLink); - - ASSERT (StatementRef->Statement->Description !=3D 0); - if (StatementRef->Statement->Description !=3D 0) { - TmpString =3D HiiGetRedfishString (StatementRef->Statement->Parent= Form->ParentFormset->HiiHandle, FullSchema, StatementRef->Statement->Descri= ption); - ASSERT (TmpString !=3D NULL); - if (TmpString !=3D NULL) { - TmpConfigureLangList[Index] =3D AllocateCopyPool (StrSize (TmpSt= ring), TmpString); - ASSERT (TmpConfigureLangList[Index] !=3D NULL); - FreePool (TmpString); - ++Index; - } - } - } - } - - *Count =3D StatementList.Count; - *ConfigureLangList =3D TmpConfigureLangList; - -RELEASE_RESOURCE: - - if (FullSchema !=3D NULL) { - FreePool (FullSchema); - } - - ReleaseStatementList (&StatementList); - - return Status; -} - - -/** - Get the list of supported Redfish schema from paltform configuration on = give HII handle. - - @param[in] This Pointer to EDKII_REDFISH_PLATFORM_CONFI= G_PROTOCOL instance. - @param[in] HiiHandle The target handle to search. If handle = is NULL, - this function return all schema from HI= I database. - @param[out] SupportedSchema The supported schema list which is sepa= rated by ';'. - The SupportedSchema is allocated by the= callee. It's caller's - responsibility to free this buffer usin= g FreePool(). - - @retval EFI_SUCCESS Schema is returned successfully. - @retval Others Some error happened. - -**/ -EFI_STATUS -EFIAPI -RedfishPlatformConfigProtocolGetSupportedSchema ( - IN EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL *This, - IN EFI_HII_HANDLE HiiHandle, OPTIONAL - OUT CHAR8 **SupportedSchema - ) -{ - REDFISH_PLATFORM_CONFIG_PRIVATE *RedfishPlatformConfigPrivate; - EFI_STATUS Status; - LIST_ENTRY *HiiFormsetLink; - LIST_ENTRY *HiiFormsetNextLink; - REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *HiiFormsetPrivate; - UINTN Index; - UINTN StringSize; - CHAR8 *StringBuffer; - UINTN StringIndex; - - if (This =3D=3D NULL || SupportedSchema =3D=3D NULL) { - return EFI_INVALID_PARAMETER; - } - - *SupportedSchema =3D NULL; - - RedfishPlatformConfigPrivate =3D REDFISH_PLATFORM_CONFIG_PRIVATE_FROM_TH= IS (This); - - Status =3D ProcessPendingList (&RedfishPlatformConfigPrivate->FormsetLis= t, &RedfishPlatformConfigPrivate->PendingList); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "%a, ProcessPendingList failure: %r\n", __FUNCTIO= N__, Status)); - return Status; - } - - if (IsListEmpty (&RedfishPlatformConfigPrivate->FormsetList)) { - return EFI_NOT_FOUND; - } - - // - // Calculate for string buffer size. - // - StringSize =3D 0; - HiiFormsetLink =3D GetFirstNode (&RedfishPlatformConfigPrivate->FormsetL= ist); - while (!IsNull (&RedfishPlatformConfigPrivate->FormsetList, HiiFormsetLi= nk)) { - HiiFormsetNextLink =3D GetNextNode (&RedfishPlatformConfigPrivate->For= msetList, HiiFormsetLink); - HiiFormsetPrivate =3D REDFISH_PLATFORM_CONFIG_FORMSET_FROM_LINK (HiiFo= rmsetLink); - - if (HiiHandle !=3D NULL && HiiHandle !=3D HiiFormsetPrivate->HiiHandle= ) { - HiiFormsetLink =3D HiiFormsetNextLink; - continue; - } - - if (HiiFormsetPrivate->SupportedSchema.Count > 0) { - for (Index =3D 0; Index < HiiFormsetPrivate->SupportedSchema.Count; = Index++) { - StringSize +=3D AsciiStrSize (HiiFormsetPrivate->SupportedSchema.S= chemaList[Index]); - } - } - - HiiFormsetLink =3D HiiFormsetNextLink; - } - - if (StringSize =3D=3D 0) { - return EFI_NOT_FOUND; - } - - StringBuffer =3D AllocatePool (StringSize); - if (StringBuffer =3D=3D NULL) { - return EFI_OUT_OF_RESOURCES; - } - - StringIndex =3D 0; - HiiFormsetLink =3D GetFirstNode (&RedfishPlatformConfigPrivate->FormsetL= ist); - while (!IsNull (&RedfishPlatformConfigPrivate->FormsetList, HiiFormsetLi= nk)) { - HiiFormsetNextLink =3D GetNextNode (&RedfishPlatformConfigPrivate->For= msetList, HiiFormsetLink); - HiiFormsetPrivate =3D REDFISH_PLATFORM_CONFIG_FORMSET_FROM_LINK (HiiFo= rmsetLink); - - if (HiiHandle !=3D NULL && HiiHandle !=3D HiiFormsetPrivate->HiiHandle= ) { - HiiFormsetLink =3D HiiFormsetNextLink; - continue; - } - - if (HiiFormsetPrivate->SupportedSchema.Count > 0) { - for (Index =3D 0; Index < HiiFormsetPrivate->SupportedSchema.Count; = Index++) { - AsciiStrCpyS (&StringBuffer[StringIndex], (StringSize - StringInde= x), HiiFormsetPrivate->SupportedSchema.SchemaList[Index]); - StringIndex +=3D AsciiStrLen (HiiFormsetPrivate->SupportedSchema.S= chemaList[Index]); - StringBuffer[StringIndex] =3D ';'; - ++StringIndex; - } - } - - HiiFormsetLink =3D HiiFormsetNextLink; - } - - StringBuffer[--StringIndex] =3D '\0'; - - *SupportedSchema =3D StringBuffer; - - return EFI_SUCCESS; -} - -/** - Functions which are registered to receive notification of - database events have this prototype. The actual event is encoded - in NotifyType. The following table describes how PackageType, - PackageGuid, Handle, and Package are used for each of the - notification types. - - @param[in] PackageType Package type of the notification. - @param[in] PackageGuid If PackageType is - EFI_HII_PACKAGE_TYPE_GUID, then this is - the pointer to the GUID from the Guid - field of EFI_HII_PACKAGE_GUID_HEADER. - Otherwise, it must be NULL. - @param[in] Package Points to the package referred to by the - notification Handle The handle of the package - list which contains the specified package. - @param[in] Handle The HII handle. - @param[in] NotifyType The type of change concerning the - database. See - EFI_HII_DATABASE_NOTIFY_TYPE. - -**/ -EFI_STATUS -EFIAPI -RedfishPlatformConfigFormUpdateNotify ( - IN UINT8 PackageType, - IN CONST EFI_GUID *PackageGuid, - IN CONST EFI_HII_PACKAGE_HEADER *Package, - IN EFI_HII_HANDLE Handle, - IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType - ) -{ - EFI_STATUS Status; - - if (NotifyType =3D=3D EFI_HII_DATABASE_NOTIFY_NEW_PACK || NotifyType =3D= =3D EFI_HII_DATABASE_NOTIFY_ADD_PACK) { - // - // HII formset on this handle is updated by driver during run-time. Th= e formset needs to be reloaded. - // - Status =3D NotifyFormsetUpdate (Handle, &mRedfishPlatformConfigPrivate= ->PendingList); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "%a, failed to notify updated formset of HII ha= ndle: 0x%x\n", __FUNCTION__, Handle)); - return Status; - } - } else if (NotifyType =3D=3D EFI_HII_DATABASE_NOTIFY_REMOVE_PACK) { - // - // HII resource is removed. The formset is no longer exist. - // - Status =3D NotifyFormsetDeleted (Handle, &mRedfishPlatformConfigPrivat= e->PendingList); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "%a, failed to notify deleted formset of HII ha= ndle: 0x%x\n", __FUNCTION__, Handle)); - return Status; - } - } - - return EFI_SUCCESS; -} - -/** - This is a EFI_HII_STRING_PROTOCOL notification event handler. - - Install HII package notification. - - @param[in] Event Event whose notification function is being invoked. - @param[in] Context Pointer to the notification function's context. - -**/ -VOID -EFIAPI -HiiStringProtocolInstalled ( - IN EFI_EVENT Event, - IN VOID *Context - ) -{ - EFI_STATUS Status; - - // - // Locate HII database protocol. - // - Status =3D gBS->LocateProtocol ( - &gEfiHiiStringProtocolGuid, - NULL, - (VOID **)&mRedfishPlatformConfigPrivate->HiiString - ); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "%a, locate EFI_HII_STRING_PROTOCOL failure: %r\n= ", __FUNCTION__, Status)); - return; - } - - gBS->CloseEvent (Event); - mRedfishPlatformConfigPrivate->HiiStringNotify.ProtocolEvent =3D NULL; -} - -/** - This is a EFI_HII_DATABASE_PROTOCOL notification event handler. - - Install HII package notification. - - @param[in] Event Event whose notification function is being invoked. - @param[in] Context Pointer to the notification function's context. - -**/ -VOID -EFIAPI -HiiDatabaseProtocolInstalled ( - IN EFI_EVENT Event, - IN VOID *Context - ) -{ - EFI_STATUS Status; - - // - // Locate HII database protocol. - // - Status =3D gBS->LocateProtocol ( - &gEfiHiiDatabaseProtocolGuid, - NULL, - (VOID **)&mRedfishPlatformConfigPrivate->HiiDatabase - ); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "%a, locate EFI_HII_DATABASE_PROTOCOL failure: %r= \n", __FUNCTION__, Status)); - return; - } - - // - // Register package notification when new form package is installed. - // - Status =3D mRedfishPlatformConfigPrivate->HiiDatabase->RegisterPackageNo= tify ( - mRedfishPlatformConfigPrivate= ->HiiDatabase, - EFI_HII_PACKAGE_FORMS, - NULL, - RedfishPlatformConfigFormUpda= teNotify, - EFI_HII_DATABASE_NOTIFY_NEW_P= ACK, - &mRedfishPlatformConfigPrivat= e->NotifyHandle - ); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "%a, RegisterPackageNotify for EFI_HII_DATABASE_N= OTIFY_NEW_PACK failure: %r\n", __FUNCTION__, Status)); - } - - // - // Register package notification when new form package is updated. - // - Status =3D mRedfishPlatformConfigPrivate->HiiDatabase->RegisterPackageNo= tify ( - mRedfishPlatformConfigPrivate= ->HiiDatabase, - EFI_HII_PACKAGE_FORMS, - NULL, - RedfishPlatformConfigFormUpda= teNotify, - EFI_HII_DATABASE_NOTIFY_ADD_P= ACK, - &mRedfishPlatformConfigPrivat= e->NotifyHandle - ); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "%a, RegisterPackageNotify for EFI_HII_DATABASE_N= OTIFY_NEW_PACK failure: %r\n", __FUNCTION__, Status)); - } - -#if REDFISH_PLATFORM_CONFIG_DELETE_EXPIRED_FORMSET - // - // Register package notification when new form package is removed. - // - Status =3D mRedfishPlatformConfigPrivate->HiiDatabase->RegisterPackageNo= tify ( - mRedfishPlatformConfigPrivate= ->HiiDatabase, - EFI_HII_PACKAGE_FORMS, - NULL, - RedfishPlatformConfigFormUpda= teNotify, - EFI_HII_DATABASE_NOTIFY_REMOV= E_PACK, - &mRedfishPlatformConfigPrivat= e->NotifyHandle - ); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "%a, RegisterPackageNotify for EFI_HII_DATABASE_N= OTIFY_NEW_PACK failure: %r\n", __FUNCTION__, Status)); - } -#endif - - gBS->CloseEvent (Event); - mRedfishPlatformConfigPrivate->HiiDbNotify.ProtocolEvent =3D NULL; - -} - -/** - This is a EFI_REGULAR_EXPRESSION_PROTOCOL notification event handler. - - @param[in] Event Event whose notification function is being invoked. - @param[in] Context Pointer to the notification function's context. - -**/ -VOID -EFIAPI -RegexProtocolInstalled ( - IN EFI_EVENT Event, - IN VOID *Context - ) -{ - EFI_STATUS Status; - - // - // Locate regular expression protocol. - // - Status =3D gBS->LocateProtocol ( - &gEfiRegularExpressionProtocolGuid, - NULL, - (VOID **)&mRedfishPlatformConfigPrivate->RegularExpressi= onProtocol - ); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "%a, locate EFI_REGULAR_EXPRESSION_PROTOCOL failu= re: %r\n", __FUNCTION__, Status)); - return; - } - - gBS->CloseEvent (Event); - mRedfishPlatformConfigPrivate->RegexNotify.ProtocolEvent =3D NULL; - -} - -/** - Unloads an image. - - @param ImageHandle Handle that identifies the image to be unl= oaded. - - @retval EFI_SUCCESS The image has been unloaded. - @retval EFI_INVALID_PARAMETER ImageHandle is not a valid image handle. - -**/ -EFI_STATUS -EFIAPI -RedfishPlatformConfigDxeUnload ( - IN EFI_HANDLE ImageHandle - ) -{ - EFI_STATUS Status; - - if (mRedfishPlatformConfigPrivate !=3D NULL) { - Status =3D gBS->UninstallProtocolInterface ( - mRedfishPlatformConfigPrivate->ImageHandle, - &gEdkIIRedfishPlatformConfigProtocolGuid, - (VOID*)&mRedfishPlatformConfigPrivate->Protocol - ); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "%a, can not uninstall gEdkIIRedfishPlatformCon= figProtocolGuid: %r\n", __FUNCTION__, Status)); - ASSERT (FALSE); - } - - // - // Close events - // - if (mRedfishPlatformConfigPrivate->HiiDbNotify.ProtocolEvent !=3D NULL= ) { - gBS->CloseEvent (mRedfishPlatformConfigPrivate->HiiDbNotify.Protocol= Event); - } - if (mRedfishPlatformConfigPrivate->HiiStringNotify.ProtocolEvent !=3D = NULL) { - gBS->CloseEvent (mRedfishPlatformConfigPrivate->HiiStringNotify.Prot= ocolEvent); - } - if (mRedfishPlatformConfigPrivate->RegexNotify.ProtocolEvent !=3D NULL= ) { - gBS->CloseEvent (mRedfishPlatformConfigPrivate->RegexNotify.Protocol= Event); - } - - // - // Unregister package notification. - // - if (mRedfishPlatformConfigPrivate->NotifyHandle !=3D NULL) { - mRedfishPlatformConfigPrivate->HiiDatabase->UnregisterPackageNotify ( - mRedfishPlatformConfigPrivate->H= iiDatabase, - mRedfishPlatformConfigPrivate->N= otifyHandle - ); - } - - ReleaseFormsetList (&mRedfishPlatformConfigPrivate->FormsetList); - FreePool (mRedfishPlatformConfigPrivate); - mRedfishPlatformConfigPrivate =3D NULL; - } - - return EFI_SUCCESS; -} - - -/** - 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 includ= ing - both device drivers and bus drivers. - - @param ImageHandle The firmware allocated handle for the UEFI= image. - @param SystemTable A pointer to the EFI System Table. - - @retval EFI_SUCCESS The operation completed successfully. - @retval Others An unexpected error occurred. -**/ -EFI_STATUS -EFIAPI -RedfishPlatformConfigDxeEntryPoint ( - IN EFI_HANDLE ImageHandle, - IN EFI_SYSTEM_TABLE *SystemTable - ) -{ - EFI_STATUS Status; - - mRedfishPlatformConfigPrivate =3D (REDFISH_PLATFORM_CONFIG_PRIVATE *)All= ocateZeroPool (sizeof (REDFISH_PLATFORM_CONFIG_PRIVATE)); - if (mRedfishPlatformConfigPrivate =3D=3D NULL) { - DEBUG ((DEBUG_ERROR, "%a, can not allocate pool for REDFISH_PLATFORM_C= ONFIG_PRIVATE\n", __FUNCTION__)); - ASSERT (FALSE); - return EFI_OUT_OF_RESOURCES; - } - - // - // Protocol initialization - // - mRedfishPlatformConfigPrivate->ImageHandle =3D ImageHandle; - mRedfishPlatformConfigPrivate->Protocol.GetValue =3D RedfishPlatformConf= igProtocolGetValue; - mRedfishPlatformConfigPrivate->Protocol.SetValue =3D RedfishPlatformConf= igProtocolSetValue; - mRedfishPlatformConfigPrivate->Protocol.GetConfigureLang =3D RedfishPlat= formConfigProtocolGetConfigureLang; - mRedfishPlatformConfigPrivate->Protocol.GetSupportedSchema =3D RedfishPl= atformConfigProtocolGetSupportedSchema; - - InitializeListHead (&mRedfishPlatformConfigPrivate->FormsetList); - InitializeListHead (&mRedfishPlatformConfigPrivate->PendingList); - - Status =3D gBS->InstallProtocolInterface ( - &ImageHandle, - &gEdkIIRedfishPlatformConfigProtocolGuid, - EFI_NATIVE_INTERFACE, - (VOID*)&mRedfishPlatformConfigPrivate->Protocol - ); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "%a, can not install gEdkIIRedfishPlatformConfigP= rotocolGuid: %r\n", __FUNCTION__, Status)); - ASSERT (FALSE); - } - - // - // Install protocol notification if HII database protocol is installed. - // - mRedfishPlatformConfigPrivate->HiiDbNotify.ProtocolEvent =3D EfiCreatePr= otocolNotifyEvent ( - &gEfiHiiData= baseProtocolGuid, - TPL_CALLBACK, - HiiDatabaseP= rotocolInstalled, - NULL, - &mRedfishPla= tformConfigPrivate->HiiDbNotify.Registration - ); - if (mRedfishPlatformConfigPrivate->HiiDbNotify.ProtocolEvent =3D=3D NULL= ) { - DEBUG ((DEBUG_ERROR, "%a, failed to create protocol notification for g= EfiHiiDatabaseProtocolGuid\n", __FUNCTION__)); - ASSERT (FALSE); - } - - // - // Install protocol notification if HII string protocol is installed. - // - mRedfishPlatformConfigPrivate->HiiStringNotify.ProtocolEvent =3D EfiCrea= teProtocolNotifyEvent ( - &gEfiHii= StringProtocolGuid, - TPL_CALL= BACK, - HiiStrin= gProtocolInstalled, - NULL, - &mRedfis= hPlatformConfigPrivate->HiiStringNotify.Registration - ); - if (mRedfishPlatformConfigPrivate->HiiStringNotify.ProtocolEvent =3D=3D = NULL) { - DEBUG ((DEBUG_ERROR, "%a, failed to create protocol notification for g= EfiHiiStringProtocolGuid\n", __FUNCTION__)); - ASSERT (FALSE); - } - - // - // Install protocol notification if regular expression protocol is insta= lled. - // - mRedfishPlatformConfigPrivate->RegexNotify.ProtocolEvent =3D EfiCreatePr= otocolNotifyEvent ( - &gEfiRegular= ExpressionProtocolGuid, - TPL_CALLBACK, - RegexProtoco= lInstalled, - NULL, - &mRedfishPla= tformConfigPrivate->RegexNotify.Registration - ); - if (mRedfishPlatformConfigPrivate->RegexNotify.ProtocolEvent =3D=3D NULL= ) { - DEBUG ((DEBUG_ERROR, "%a, failed to create protocol notification for g= EfiRegularExpressionProtocolGuid\n", __FUNCTION__)); - ASSERT (FALSE); - } - - return EFI_SUCCESS; -} +/** @file + + The implementation of EDKII Redfidh Platform Config Protocol. + + (C) Copyright 2021-2022 Hewlett Packard Enterprise Development LP
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "RedfishPlatformConfigDxe.h" +#include "RedfishPlatformConfigImpl.h" + +REDFISH_PLATFORM_CONFIG_PRIVATE *mRedfishPlatformConfigPrivate =3D NULL; + + +/** + Zero extend integer/boolean to UINT64 for comparing. + + @param Value HII Value to be converted. + +**/ +UINT64 +ExtendHiiValueToU64 ( + IN HII_STATEMENT_VALUE *Value + ) +{ + UINT64 Temp; + + Temp =3D 0; + switch (Value->Type) { + case EFI_IFR_TYPE_NUM_SIZE_8: + Temp =3D Value->Value.u8; + break; + + case EFI_IFR_TYPE_NUM_SIZE_16: + Temp =3D Value->Value.u16; + break; + + case EFI_IFR_TYPE_NUM_SIZE_32: + Temp =3D Value->Value.u32; + break; + + case EFI_IFR_TYPE_BOOLEAN: + Temp =3D Value->Value.b; + break; + + case EFI_IFR_TYPE_TIME: + case EFI_IFR_TYPE_DATE: + default: + break; + } + + return Temp; +} + +/** + Set value of a data element in an Array by its Index in ordered list buf= fer. + + @param Array The data array. + @param Type Type of the data in this array. + @param Index Zero based index for data in this array. + @param Value The value to be set. + +**/ +VOID +OrderedListSetArrayData ( + IN VOID *Array, + IN UINT8 Type, + IN UINTN Index, + IN UINT64 Value + ) +{ + + ASSERT (Array !=3D NULL); + + switch (Type) { + case EFI_IFR_TYPE_NUM_SIZE_8: + *(((UINT8 *) Array) + Index) =3D (UINT8) Value; + break; + + case EFI_IFR_TYPE_NUM_SIZE_16: + *(((UINT16 *) Array) + Index) =3D (UINT16) Value; + break; + + case EFI_IFR_TYPE_NUM_SIZE_32: + *(((UINT32 *) Array) + Index) =3D (UINT32) Value; + break; + + case EFI_IFR_TYPE_NUM_SIZE_64: + *(((UINT64 *) Array) + Index) =3D (UINT64) Value; + break; + + default: + break; + } +} + +/** + Return data element in an Array by its Index in ordered list array buffe= r. + + @param Array The data array. + @param Type Type of the data in this array. + @param Index Zero based index for data in this array. + + @retval Value The data to be returned + +**/ +UINT64 +OrderedListGetArrayData ( + IN VOID *Array, + IN UINT8 Type, + IN UINTN Index + ) +{ + UINT64 Data; + + ASSERT (Array !=3D NULL); + + Data =3D 0; + switch (Type) { + case EFI_IFR_TYPE_NUM_SIZE_8: + Data =3D (UINT64) *(((UINT8 *) Array) + Index); + break; + + case EFI_IFR_TYPE_NUM_SIZE_16: + Data =3D (UINT64) *(((UINT16 *) Array) + Index); + break; + + case EFI_IFR_TYPE_NUM_SIZE_32: + Data =3D (UINT64) *(((UINT32 *) Array) + Index); + break; + + case EFI_IFR_TYPE_NUM_SIZE_64: + Data =3D (UINT64) *(((UINT64 *) Array) + Index); + break; + + default: + break; + } + + return Data; +} + +/** + Find string ID of option if its value equals to given value. + + @param[in] HiiStatement Statement to search. + @param[in] Value Target value. + + @retval EFI_SUCCESS HII value is returned successfully. + @retval Others Errors occur + +**/ +EFI_STRING_ID +OrderedListOptionValueToStringId ( + IN HII_STATEMENT *HiiStatement, + IN UINT64 Value + ) +{ + LIST_ENTRY *Link; + HII_QUESTION_OPTION *Option; + BOOLEAN Found; + UINT64 CurrentValue; + + if (HiiStatement =3D=3D NULL) { + return 0; + } + + if (HiiStatement->Operand !=3D EFI_IFR_ORDERED_LIST_OP) { + return 0; + } + + if (IsListEmpty (&HiiStatement->OptionListHead)) { + return 0; + } + + Found =3D FALSE; + Link =3D GetFirstNode (&HiiStatement->OptionListHead); + while (!IsNull (&HiiStatement->OptionListHead, Link)) { + Option =3D HII_QUESTION_OPTION_FROM_LINK (Link); + + CurrentValue =3D ExtendHiiValueToU64 (&Option->Value); + if (Value =3D=3D CurrentValue) { + return Option->Text; + } + + Link =3D GetNextNode (&HiiStatement->OptionListHead, Link); + } + + return 0; +} + +/** + Compare two value in HII statement format. + + @param[in] Value1 Firt value to compare. + @param[in] Value2 Second value to be compared. + + @retval INTN 0 is retuned when two values are equal. + 1 is returned when first value is greater than sec= ond value. + -1 is returned when second value is greater than f= irst value. + +**/ +INTN +CompareHiiStatementValue ( + IN HII_STATEMENT_VALUE *Value1, + IN HII_STATEMENT_VALUE *Value2 + ) +{ + INTN Result; + UINT64 Data1; + UINT64 Data2; + + if (Value1 =3D=3D NULL || Value2 =3D=3D NULL) { + return -1; + } + + switch (Value1->Type) { + case EFI_IFR_TYPE_NUM_SIZE_8: + Data1 =3D Value1->Value.u8; + break; + case EFI_IFR_TYPE_NUM_SIZE_16: + Data1 =3D Value1->Value.u16; + break; + case EFI_IFR_TYPE_NUM_SIZE_32: + Data1 =3D Value1->Value.u32; + break; + case EFI_IFR_TYPE_NUM_SIZE_64: + Data1 =3D Value1->Value.u64; + break; + case EFI_IFR_TYPE_BOOLEAN: + Data1 =3D (Value1->Value.b ? 1 : 0); + break; + default: + return -1; + } + + switch (Value2->Type) { + case EFI_IFR_TYPE_NUM_SIZE_8: + Data2 =3D Value2->Value.u8; + break; + case EFI_IFR_TYPE_NUM_SIZE_16: + Data2 =3D Value2->Value.u16; + break; + case EFI_IFR_TYPE_NUM_SIZE_32: + Data2 =3D Value2->Value.u32; + break; + case EFI_IFR_TYPE_NUM_SIZE_64: + Data2 =3D Value2->Value.u64; + break; + case EFI_IFR_TYPE_BOOLEAN: + Data2 =3D (Value2->Value.b ? 1 : 0); + break; + default: + return -1; + } + + Result =3D (Data1 =3D=3D Data2 ? 0 : (Data1 > Data2 ? 1 : -1)); + + return Result; +} + +/** + Convert HII value to the string in HII one-of opcode. + + @param[in] Statement Statement private instance + + @retval EFI_STRING_ID The string ID in HII database. + 0 is returned when something goes wrong. + +**/ +EFI_STRING_ID +HiiValueToOneOfOptionStringId ( + IN REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE *Statement + ) +{ + LIST_ENTRY *Link; + HII_QUESTION_OPTION *Option; + + if (Statement->HiiStatement->Operand !=3D EFI_IFR_ONE_OF_OP) { + return 0; + } + + if (IsListEmpty (&Statement->HiiStatement->OptionListHead)) { + return 0; + } + + Link =3D GetFirstNode (&Statement->HiiStatement->OptionListHead); + while (!IsNull (&Statement->HiiStatement->OptionListHead, Link)) { + Option =3D HII_QUESTION_OPTION_FROM_LINK (Link); + + if (CompareHiiStatementValue (&Statement->HiiStatement->Value, &Option= ->Value) =3D=3D 0) { + return Option->Text; + } + + Link =3D GetNextNode (&Statement->HiiStatement->OptionListHead, Link); + } + + return 0; +} + +/** + Convert HII string to the value in HII one-of opcode. + + @param[in] Statement Statement private instance + @param[in] Schema Schema string + @param[in] HiiString Input string + @param[out] Value Value returned + + @retval EFI_SUCCESS HII value is returned successfully. + @retval Others Errors occur + +**/ +EFI_STATUS +HiiStringToOneOfOptionValue ( + IN REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE *Statement, + IN CHAR8 *Schema, + IN EFI_STRING HiiString, + OUT HII_STATEMENT_VALUE *Value + ) +{ + LIST_ENTRY *Link; + HII_QUESTION_OPTION *Option; + EFI_STRING TmpString; + BOOLEAN Found; + + if (Statement =3D=3D NULL || IS_EMPTY_STRING (HiiString) || Value =3D=3D= NULL) { + return EFI_INVALID_PARAMETER; + } + + if (Statement->HiiStatement->Operand !=3D EFI_IFR_ONE_OF_OP) { + return EFI_UNSUPPORTED; + } + + if (IsListEmpty (&Statement->HiiStatement->OptionListHead)) { + return EFI_NOT_FOUND; + } + + Found =3D FALSE; + Link =3D GetFirstNode (&Statement->HiiStatement->OptionListHead); + while (!IsNull (&Statement->HiiStatement->OptionListHead, Link)) { + Option =3D HII_QUESTION_OPTION_FROM_LINK (Link); + + TmpString =3D HiiGetRedfishString (Statement->ParentForm->ParentFormse= t->HiiHandle, Schema, Option->Text); + if (TmpString !=3D NULL) { + if (StrCmp (TmpString, HiiString) =3D=3D 0) { + CopyMem (Value, &Option->Value, sizeof (HII_STATEMENT_VALUE)); + Found =3D TRUE; + } + FreePool (TmpString); + } + + if (Found) { + return EFI_SUCCESS; + } + + Link =3D GetNextNode (&Statement->HiiStatement->OptionListHead, Link); + } + + return EFI_NOT_FOUND; +} + +/** + Convert HII value to numeric value in Redfish format. + + @param[in] Value Value to be converted. + @param[out] RedfishValue Value in Redfish format. + + @retval EFI_SUCCESS Redfish value is returned successfully. + @retval Others Errors occur + +**/ +EFI_STATUS +HiiValueToRedfishNumeric ( + IN HII_STATEMENT_VALUE *Value, + OUT EDKII_REDFISH_VALUE *RedfishValue + ) +{ + if (Value =3D=3D NULL || RedfishValue =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + + switch (Value->Type) { + case EFI_IFR_TYPE_NUM_SIZE_8: + RedfishValue->Type =3D REDFISH_VALUE_TYPE_INTEGER; + RedfishValue->Value.Integer =3D (INT64)Value->Value.u8; + break; + case EFI_IFR_TYPE_NUM_SIZE_16: + RedfishValue->Type =3D REDFISH_VALUE_TYPE_INTEGER; + RedfishValue->Value.Integer =3D (INT64)Value->Value.u16; + break; + case EFI_IFR_TYPE_NUM_SIZE_32: + RedfishValue->Type =3D REDFISH_VALUE_TYPE_INTEGER; + RedfishValue->Value.Integer =3D (INT64)Value->Value.u32; + break; + case EFI_IFR_TYPE_NUM_SIZE_64: + RedfishValue->Type =3D REDFISH_VALUE_TYPE_INTEGER; + RedfishValue->Value.Integer =3D (INT64)Value->Value.u64; + break; + case EFI_IFR_TYPE_BOOLEAN: + RedfishValue->Type =3D REDFISH_VALUE_TYPE_BOOLEAN; + RedfishValue->Value.Boolean =3D Value->Value.b; + break; + default: + RedfishValue->Type =3D REDFISH_VALUE_TYPE_UNKNOWN; + break; + } + + return EFI_SUCCESS; +} + +/** + Convert numeric value in Redfish format to HII value. + + @param[in] RedfishValue Value in Redfish format to be converted. + @param[out] Value HII value returned. + + @retval EFI_SUCCESS HII value is returned successfully. + @retval Others Errors occur + +**/ +EFI_STATUS +RedfishNumericToHiiValue ( + IN EDKII_REDFISH_VALUE *RedfishValue, + OUT HII_STATEMENT_VALUE *Value + ) +{ + if (Value =3D=3D NULL || RedfishValue =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + + switch (RedfishValue->Type) { + case REDFISH_VALUE_TYPE_INTEGER: + Value->Type =3D EFI_IFR_TYPE_NUM_SIZE_64; + Value->Value.u64 =3D (UINT64)RedfishValue->Value.Integer; + break; + case REDFISH_VALUE_TYPE_BOOLEAN: + Value->Type =3D EFI_IFR_TYPE_BOOLEAN; + Value->Value.b =3D RedfishValue->Value.Boolean; + break; + default: + Value->Type =3D EFI_IFR_TYPE_UNDEFINED; + break; + } + + return EFI_SUCCESS; +} + +/** + Dump the value in ordered list buffer. + + @param[in] OrderedListStatement Ordered list statement. + +**/ +VOID +DumpOrderedListValue ( + IN HII_STATEMENT *OrderedListStatement + ) +{ + UINT8 *Value8; + UINT16 *Value16; + UINT32 *Value32; + UINT64 *Value64; + UINTN Count; + UINTN Index; + + if (OrderedListStatement =3D=3D NULL || OrderedListStatement->Operand != =3D EFI_IFR_ORDERED_LIST_OP) { + return; + } + + DEBUG ((DEBUG_ERROR, "Value.Type=3D 0x%x\n", OrderedListStatement->Value= .Type)); + DEBUG ((DEBUG_ERROR, "Value.BufferValueType=3D 0x%x\n", OrderedListState= ment->Value.BufferValueType)); + DEBUG ((DEBUG_ERROR, "Value.BufferLen=3D 0x%x\n", OrderedListStatement->= Value.BufferLen)); + DEBUG ((DEBUG_ERROR, "Value.Buffer=3D 0x%x\n", OrderedListStatement->Val= ue.Buffer)); + DEBUG ((DEBUG_ERROR, "Value.MaxContainers=3D 0x%x\n", OrderedListStateme= nt->ExtraData.OrderListData.MaxContainers)); + DEBUG ((DEBUG_ERROR, "StorageWidth=3D 0x%x\n", OrderedListStatement->Sto= rageWidth)); + + if (OrderedListStatement->Value.Buffer =3D=3D NULL) { + return; + } + + Value8 =3D NULL; + Value16 =3D NULL; + Value32 =3D NULL; + Value64 =3D NULL; + Count =3D 0; + + switch (OrderedListStatement->Value.BufferValueType) { + case EFI_IFR_TYPE_NUM_SIZE_8: + Value8 =3D (UINT8 *)OrderedListStatement->Value.Buffer; + Count =3D OrderedListStatement->StorageWidth / sizeof (UINT8); + for (Index =3D 0; Index < Count; Index++) { + DEBUG ((DEBUG_ERROR, "%d ", Value8[Index])); + } + break; + case EFI_IFR_TYPE_NUM_SIZE_16: + Value16 =3D (UINT16 *)OrderedListStatement->Value.Buffer; + Count =3D OrderedListStatement->StorageWidth / sizeof (UINT16); + for (Index =3D 0; Index < Count; Index++) { + DEBUG ((DEBUG_ERROR, "%d ", Value16[Index])); + } + break; + case EFI_IFR_TYPE_NUM_SIZE_32: + Value32 =3D (UINT32 *)OrderedListStatement->Value.Buffer; + Count =3D OrderedListStatement->StorageWidth / sizeof (UINT32); + for (Index =3D 0; Index < Count; Index++) { + DEBUG ((DEBUG_ERROR, "%d ", Value32[Index])); + } + break; + case EFI_IFR_TYPE_NUM_SIZE_64: + Value64 =3D (UINT64 *)OrderedListStatement->Value.Buffer; + Count =3D OrderedListStatement->StorageWidth / sizeof (UINT64); + for (Index =3D 0; Index < Count; Index++) { + DEBUG ((DEBUG_ERROR, "%d ", Value64[Index])); + } + break; + default: + Value8 =3D (UINT8 *)OrderedListStatement->Value.Buffer; + Count =3D OrderedListStatement->StorageWidth / sizeof (UINT8); + for (Index =3D 0; Index < Count; Index++) { + DEBUG ((DEBUG_ERROR, "%d ", Value8[Index])); + } + break; + } + + DEBUG ((DEBUG_ERROR, "\n")); +} + +/** + Convert HII value to the string in HII ordered list opcode. It's caller's + responsibility to free returned buffer using FreePool(). + + @param[in] Statement Statement private instance + @param[out] ReturnSize The size of returned array + + @retval EFI_STRING_ID The string ID array for options in ordered lis= t. + +**/ +EFI_STRING_ID * +HiiValueToOrderedListOptionStringId ( + IN REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE *Statement, + OUT UINTN *ReturnSize + ) +{ + LIST_ENTRY *Link; + HII_QUESTION_OPTION *Option; + UINTN OptionCount; + EFI_STRING_ID *ReturnedArray; + UINTN Index; + UINT64 Value; + + if (Statement =3D=3D NULL || ReturnSize =3D=3D NULL) { + return NULL; + } + + *ReturnSize =3D 0; + + if (Statement->HiiStatement->Operand !=3D EFI_IFR_ORDERED_LIST_OP) { + return NULL; + } + + if (IsListEmpty (&Statement->HiiStatement->OptionListHead)) { + return NULL; + } + + DEBUG_CODE ( + DumpOrderedListValue (Statement->HiiStatement); + ); + + OptionCount =3D 0; + Link =3D GetFirstNode (&Statement->HiiStatement->OptionListHead); + while (!IsNull (&Statement->HiiStatement->OptionListHead, Link)) { + Option =3D HII_QUESTION_OPTION_FROM_LINK (Link); + + ++OptionCount; + + Link =3D GetNextNode (&Statement->HiiStatement->OptionListHead, Link); + } + + *ReturnSize =3D OptionCount; + ReturnedArray =3D AllocatePool (sizeof (EFI_STRING_ID) * OptionCount); + if (ReturnedArray =3D=3D NULL) { + DEBUG ((DEBUG_ERROR, "%a, out of resource\n", __FUNCTION__)); + *ReturnSize =3D 0; + return NULL; + } + + for (Index =3D 0; Index < OptionCount; Index++) { + Value =3D OrderedListGetArrayData (Statement->HiiStatement->Value.Buff= er, Statement->HiiStatement->Value.BufferValueType, Index); + ReturnedArray[Index] =3D OrderedListOptionValueToStringId (Statement->= HiiStatement, Value); + } + + return ReturnedArray; +} + +/** + Convert HII string to the value in HII ordered list opcode. + + @param[in] Statement Statement private instance + @param[in] Schema Schema string + @param[in] HiiString Input string + @param[out] Value Value returned + + @retval EFI_SUCCESS HII value is returned successfully. + @retval Others Errors occur + +**/ +EFI_STATUS +HiiStringToOrderedListOptionValue ( + IN REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE *Statement, + IN CHAR8 *Schema, + IN EFI_STRING HiiString, + OUT UINT64 *Value + ) +{ + LIST_ENTRY *Link; + HII_QUESTION_OPTION *Option; + EFI_STRING TmpString; + BOOLEAN Found; + + if (Statement =3D=3D NULL || IS_EMPTY_STRING (HiiString) || Value =3D=3D= NULL) { + return EFI_INVALID_PARAMETER; + } + + *Value =3D 0; + + if (Statement->HiiStatement->Operand !=3D EFI_IFR_ORDERED_LIST_OP) { + return EFI_UNSUPPORTED; + } + + if (IsListEmpty (&Statement->HiiStatement->OptionListHead)) { + return EFI_NOT_FOUND; + } + + Found =3D FALSE; + Link =3D GetFirstNode (&Statement->HiiStatement->OptionListHead); + while (!IsNull (&Statement->HiiStatement->OptionListHead, Link)) { + Option =3D HII_QUESTION_OPTION_FROM_LINK (Link); + + TmpString =3D HiiGetRedfishString (Statement->ParentForm->ParentFormse= t->HiiHandle, Schema, Option->Text); + if (TmpString !=3D NULL) { + if (StrCmp (TmpString, HiiString) =3D=3D 0) { + *Value =3D ExtendHiiValueToU64 (&Option->Value); + Found =3D TRUE; + } + FreePool (TmpString); + } + + if (Found) { + return EFI_SUCCESS; + } + + Link =3D GetNextNode (&Statement->HiiStatement->OptionListHead, Link); + } + + return EFI_NOT_FOUND; +} + +/** + Convert input ascii string to unicode string. It's caller's + responsibility to free returned buffer using FreePool(). + + @param[in] AsciiString Ascii string to be converted. + + @retval CHAR16 * Unicode string on return. + +**/ +EFI_STRING +StrToUnicodeStr ( + IN CHAR8 *AsciiString + ) +{ + UINTN StringLen; + EFI_STRING Buffer; + EFI_STATUS Status; + + if (AsciiString =3D=3D NULL || AsciiString[0] =3D=3D '\0') { + return NULL; + } + + StringLen =3D AsciiStrLen (AsciiString) + 1; + Buffer =3D AllocatePool (StringLen * sizeof (CHAR16)); + if (Buffer =3D=3D NULL) { + return NULL; + } + + Status =3D AsciiStrToUnicodeStrS (AsciiString, Buffer, StringLen); + if (EFI_ERROR (Status)) { + FreePool (Buffer); + return NULL; + } + + return Buffer; +} + +/** + Return the full Redfish schema string from the given Schema and Version. + + Returned schema string is: Schema + '.' + Version + + @param[in] Schema Schema string + @param[in] Version Schema version string + + @retval CHAR8 * Schema string. NULL when errors occur. + +**/ +CHAR8 * +GetFullSchemaString ( + IN CHAR8 *Schema, + IN CHAR8 *Version + ) +{ + UINTN Size; + CHAR8 *FullName; + + if (IS_EMPTY_STRING (Schema) || IS_EMPTY_STRING (Version)) { + return NULL; + } + + Size =3D AsciiStrSize(CONFIGURE_LANGUAGE_PREFIX) + AsciiStrSize (Schema)= + AsciiStrSize (Version); + + FullName =3D AllocatePool (Size); + if (FullName =3D=3D NULL) { + DEBUG ((DEBUG_ERROR, "%a, out-of-resource\n", __FUNCTION__)); + return NULL; + } + + AsciiSPrint (FullName, Size, "%a%a.%a", CONFIGURE_LANGUAGE_PREFIX, Schem= a, Version); + + return FullName; +} + +/** + Common implementation to get statement private instance. + + @param[in] RedfishPlatformConfigPrivate Private instance. + @param[in] Schema Redfish schema string. + @param[in] ConfigureLang Configure language that refe= rs to this statement. + @param[out] Statement Statement instance + + @retval EFI_SUCCESS HII value is returned successfully. + @retval Others Errors occur + +**/ +EFI_STATUS +RedfishPlatformConfigGetStatementCommon ( + IN REDFISH_PLATFORM_CONFIG_PRIVATE *RedfishPlatformConfig= Private, + IN CHAR8 *Schema, + IN EFI_STRING ConfigureLang, + OUT REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE **Statement + ) +{ + EFI_STATUS Status; + REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE *TargetStatement; + + if (RedfishPlatformConfigPrivate =3D=3D NULL || IS_EMPTY_STRING (Schema)= || IS_EMPTY_STRING (ConfigureLang) || Statement =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + + *Statement =3D NULL; + + Status =3D ProcessPendingList (&RedfishPlatformConfigPrivate->FormsetLis= t, &RedfishPlatformConfigPrivate->PendingList); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a, ProcessPendingList failure: %r\n", __FUNCTIO= N__, Status)); + return Status; + } + + TargetStatement =3D GetStatementPrivateByConfigureLang (&RedfishPlatform= ConfigPrivate->FormsetList, Schema, ConfigureLang); + if (TargetStatement =3D=3D NULL) { + DEBUG ((DEBUG_ERROR, "%a, No match HII statement is found by the given= %s in schema %a\n", __FUNCTION__, ConfigureLang, Schema)); + return EFI_NOT_FOUND; + } + + // + // Find current HII question value. + // + Status =3D GetQuestionValue ( + TargetStatement->ParentForm->ParentFormset->HiiFormSet, + TargetStatement->ParentForm->HiiForm, + TargetStatement->HiiStatement, + GetSetValueWithHiiDriver + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a, failed to get question current value: %r\n",= __FUNCTION__, Status)); + return Status; + } + + + if (TargetStatement->HiiStatement->Value.Type =3D=3D EFI_IFR_TYPE_UNDEFI= NED) { + return EFI_DEVICE_ERROR; + } + + // + // Return Value. + // + *Statement =3D TargetStatement; + + return EFI_SUCCESS; +} + +/** + Get Redfish value with the given Schema and Configure Language. + + @param[in] This Pointer to EDKII_REDFISH_PLATFORM_CONFI= G_PROTOCOL instance. + @param[in] Schema The Redfish schema to query. + @param[in] Version The Redfish version to query. + @param[in] ConfigureLang The target value which match this confi= gure Language. + @param[out] Value The returned value. + + @retval EFI_SUCCESS Value is returned successfully. + @retval Others Some error happened. + +**/ +EFI_STATUS +EFIAPI +RedfishPlatformConfigProtocolGetValue ( + IN EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL *This, + IN CHAR8 *Schema, + IN CHAR8 *Version, + IN EFI_STRING ConfigureLang, + OUT EDKII_REDFISH_VALUE *Value + ) +{ + EFI_STATUS Status; + REDFISH_PLATFORM_CONFIG_PRIVATE *RedfishPlatformConfigPrivate; + REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE *TargetStatement; + EFI_STRING_ID StringId; + EFI_STRING_ID *StringIdArray; + CHAR8 *FullSchema; + EFI_STRING HiiString; + UINTN Count; + UINTN Index; + + if (This =3D=3D NULL || IS_EMPTY_STRING (Schema) || IS_EMPTY_STRING (Ver= sion) || IS_EMPTY_STRING (ConfigureLang) || Value =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + + RedfishPlatformConfigPrivate =3D REDFISH_PLATFORM_CONFIG_PRIVATE_FROM_TH= IS (This); + Value->Type =3D REDFISH_VALUE_TYPE_UNKNOWN; + Value->ArrayCount =3D 0; + Count =3D 0; + FullSchema =3D NULL; + HiiString =3D NULL; + StringIdArray =3D NULL; + + FullSchema =3D GetFullSchemaString (Schema, Version); + if (FullSchema =3D=3D NULL) { + return EFI_OUT_OF_RESOURCES; + } + + Status =3D RedfishPlatformConfigGetStatementCommon (RedfishPlatformConfi= gPrivate, FullSchema, ConfigureLang, &TargetStatement); + if (EFI_ERROR (Status)) { + goto RELEASE_RESOURCE; + } + + switch (TargetStatement->HiiStatement->Operand) { + case EFI_IFR_ONE_OF_OP: + StringId =3D HiiValueToOneOfOptionStringId (TargetStatement); + if (StringId =3D=3D 0) { + ASSERT (FALSE); + Status =3D EFI_DEVICE_ERROR; + goto RELEASE_RESOURCE; + } + + Value->Value.Buffer =3D HiiGetRedfishAsciiString (TargetStatement->P= arentForm->ParentFormset->HiiHandle, FullSchema, StringId); + if (Value->Value.Buffer =3D=3D NULL) { + Status =3D EFI_OUT_OF_RESOURCES; + goto RELEASE_RESOURCE; + } + + Value->Type =3D REDFISH_VALUE_TYPE_STRING; + break; + case EFI_IFR_STRING_OP: + if (TargetStatement->HiiStatement->Value.Type !=3D EFI_IFR_TYPE_STRI= NG) { + ASSERT (FALSE); + Status =3D EFI_DEVICE_ERROR; + goto RELEASE_RESOURCE; + } + + Value->Type =3D REDFISH_VALUE_TYPE_STRING; + Value->Value.Buffer =3D AllocatePool (StrLen ((CHAR16 *)TargetStatem= ent->HiiStatement->Value.Buffer) + 1); + UnicodeStrToAsciiStrS ((CHAR16 *)TargetStatement->HiiStatement->Valu= e.Buffer, Value->Value.Buffer, StrLen ((CHAR16 *)TargetStatement->HiiStatem= ent->Value.Buffer) + 1); + break; + case EFI_IFR_CHECKBOX_OP: + case EFI_IFR_NUMERIC_OP: + Status =3D HiiValueToRedfishNumeric (&TargetStatement->HiiStatement-= >Value, Value); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a, failed to convert HII value to Redfish v= alue: %r\n", __FUNCTION__, Status)); + goto RELEASE_RESOURCE; + } + break; + case EFI_IFR_ACTION_OP: + if (TargetStatement->HiiStatement->Value.Type !=3D EFI_IFR_TYPE_ACTI= ON) { + ASSERT (FALSE); + Status =3D EFI_DEVICE_ERROR; + goto RELEASE_RESOURCE; + } + + // + // Action has no value. Just return unknown type. + // + Value->Type =3D REDFISH_VALUE_TYPE_UNKNOWN; + break; + case EFI_IFR_ORDERED_LIST_OP: + StringIdArray =3D HiiValueToOrderedListOptionStringId (TargetStateme= nt, &Count); + if (StringIdArray =3D=3D NULL) { + ASSERT (FALSE); + Status =3D EFI_DEVICE_ERROR; + goto RELEASE_RESOURCE; + } + + Value->Value.StringArray =3D AllocatePool (sizeof (CHAR8 *) * Count); + if (Value->Value.StringArray =3D=3D NULL) { + ASSERT (FALSE); + Status =3D EFI_OUT_OF_RESOURCES; + goto RELEASE_RESOURCE; + } + + for (Index =3D 0; Index < Count; Index++) { + ASSERT (StringIdArray[Index] !=3D 0); + Value->Value.StringArray[Index] =3D HiiGetRedfishAsciiString (Targ= etStatement->ParentForm->ParentFormset->HiiHandle, FullSchema, StringIdArra= y[Index]); + } + + Value->ArrayCount =3D Count; + Value->Type =3D REDFISH_VALUE_TYPE_STRING_ARRAY; + break; + default: + DEBUG ((DEBUG_ERROR, "%a, catch unsupported type: 0x%x! Please conta= ct with author if we need to support this type.\n", __FUNCTION__, TargetSta= tement->HiiStatement->Operand)); + ASSERT (FALSE); + Status =3D EFI_UNSUPPORTED; + goto RELEASE_RESOURCE; + } + +RELEASE_RESOURCE: + + if (FullSchema !=3D NULL) { + FreePool (FullSchema); + } + + if (HiiString !=3D NULL) { + FreePool (HiiString); + } + + if (StringIdArray !=3D NULL) { + FreePool (StringIdArray); + } + + return Status; +} + +/** + Function to save question value into HII database. + + @param[in] HiiFormset HII form-set instance + @param[in] HiiForm HII form instance + @param[in] HiiStatement HII statement that keeps new value. + @param[in] Value New value to applyu. + + @retval EFI_SUCCESS HII value is returned successfully. + @retval Others Errors occur + +**/ +EFI_STATUS +RedfishPlatformConfigSaveQuestionValue ( + IN HII_FORMSET *HiiFormset, + IN HII_FORM *HiiForm, + IN HII_STATEMENT *HiiStatement, + IN HII_STATEMENT_VALUE *Value + ) +{ + EFI_STATUS Status; + + if (HiiFormset =3D=3D NULL || HiiForm =3D=3D NULL || HiiStatement =3D=3D= NULL || Value =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + + Status =3D SetQuestionValue ( + HiiFormset, + HiiForm, + HiiStatement, + Value + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a, failed to set question value: %r\n", __FUNCT= ION__, Status)); + return Status; + } + + Status =3D SubmitForm (HiiFormset, HiiForm); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a, failed to submit form: %r\n", __FUNCTION__, = Status)); + return Status; + } + + return EFI_SUCCESS; +} + +/** + Common implementation to set statement private instance. + + @param[in] RedfishPlatformConfigPrivate Private instance. + @param[in] Schema Redfish schema string. + @param[in] ConfigureLang Configure language that refe= rs to this statement. + @param[in] Statement Statement instance + + @retval EFI_SUCCESS HII value is returned successfully. + @retval Others Errors occur + +**/ +EFI_STATUS +RedfishPlatformConfigSetStatementCommon ( + IN REDFISH_PLATFORM_CONFIG_PRIVATE *RedfishPlatformConfigPrivate, + IN CHAR8 *Schema, + IN EFI_STRING ConfigureLang, + IN HII_STATEMENT_VALUE *StatementValue + ) +{ + EFI_STATUS Status; + REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE *TargetStatement; + EFI_STRING TempBuffer; + UINT8 *StringArray; + UINTN Index; + UINT64 Value; + CHAR8 **CharArray; + + if (RedfishPlatformConfigPrivate =3D=3D NULL || IS_EMPTY_STRING (Schema)= || IS_EMPTY_STRING (ConfigureLang) || StatementValue =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + + TempBuffer =3D NULL; + StringArray =3D NULL; + + Status =3D ProcessPendingList (&RedfishPlatformConfigPrivate->FormsetLis= t, &RedfishPlatformConfigPrivate->PendingList); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a, ProcessPendingList failure: %r\n", __FUNCTIO= N__, Status)); + return Status; + } + + TargetStatement =3D GetStatementPrivateByConfigureLang (&RedfishPlatform= ConfigPrivate->FormsetList, Schema, ConfigureLang); + if (TargetStatement =3D=3D NULL) { + DEBUG ((DEBUG_ERROR, "%a, No match HII statement is found by the given= %s in schema %a\n", __FUNCTION__, ConfigureLang, Schema)); + return EFI_NOT_FOUND; + } + + if (StatementValue->Type !=3D TargetStatement->HiiStatement->Value.Type)= { + // + // We treat one-of type as string in Redfish. But one-of statement is = not + // in string format from HII point of view. Do a patch here. + // + if (TargetStatement->HiiStatement->Operand =3D=3D EFI_IFR_ONE_OF_OP &&= StatementValue->Type =3D=3D EFI_IFR_TYPE_STRING) { + + TempBuffer =3D StrToUnicodeStr ((CHAR8 *)StatementValue->Buffer); + if (TempBuffer =3D=3D NULL) { + return EFI_OUT_OF_RESOURCES; + } + FreePool (StatementValue->Buffer); + StatementValue->Buffer =3D NULL; + StatementValue->BufferLen =3D 0; + + Status =3D HiiStringToOneOfOptionValue (TargetStatement, Schema, Tem= pBuffer, StatementValue); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a, failed to find option value by the given= %s\n", __FUNCTION__, TempBuffer)); + FreePool (TempBuffer); + return EFI_NOT_FOUND; + } + + FreePool (TempBuffer); + } else if (TargetStatement->HiiStatement->Operand =3D=3D EFI_IFR_ORDER= ED_LIST_OP && StatementValue->Type =3D=3D EFI_IFR_TYPE_STRING) { + // + // We treat ordered list type as string in Redfish. But ordered list= statement is not + // in string format from HII point of view. Do a patch here. + // + StringArray =3D AllocateZeroPool (TargetStatement->HiiStatement->Sto= rageWidth); + if (StringArray =3D=3D NULL) { + return EFI_OUT_OF_RESOURCES; + } + + // + // Arrage new option order from input string array + // + CharArray =3D (CHAR8 **)StatementValue->Buffer; + for (Index =3D 0; Index < StatementValue->BufferLen; Index++) { + TempBuffer =3D StrToUnicodeStr (CharArray[Index]); + if (TempBuffer =3D=3D NULL) { + return EFI_OUT_OF_RESOURCES; + } + + Status =3D HiiStringToOrderedListOptionValue (TargetStatement, Sch= ema, TempBuffer, &Value); + if (EFI_ERROR (Status)) { + ASSERT (FALSE); + continue; + } + FreePool (TempBuffer); + OrderedListSetArrayData (StringArray, TargetStatement->HiiStatemen= t->Value.BufferValueType, Index, Value); + } + + StatementValue->Type =3D EFI_IFR_TYPE_BUFFER; + StatementValue->Buffer =3D StringArray; + StatementValue->BufferLen =3D TargetStatement->HiiStatement->Storage= Width; + StatementValue->BufferValueType =3D TargetStatement->HiiStatement->V= alue.BufferValueType; + } else if (TargetStatement->HiiStatement->Operand =3D=3D EFI_IFR_NUMER= IC_OP && StatementValue->Type =3D=3D EFI_IFR_TYPE_NUM_SIZE_64) { + // + // Redfish only has numeric value type and it does not care about th= e value size. + // Do a patch here so we have proper value size applied. + // + StatementValue->Type =3D TargetStatement->HiiStatement->Value.Type; + } else { + DEBUG ((DEBUG_ERROR, "%a, catch value type mismatch! input type: 0x%= x but target value type: 0x%x\n", __FUNCTION__, StatementValue->Type, Targe= tStatement->HiiStatement->Value.Type)); + ASSERT (FALSE); + } + } + + Status =3D RedfishPlatformConfigSaveQuestionValue ( + TargetStatement->ParentForm->ParentFormset->HiiFormSet, + TargetStatement->ParentForm->HiiForm, + TargetStatement->HiiStatement, + StatementValue + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a, failed to save question value: %r\n", __FUNC= TION__, Status)); + return Status; + } + + return EFI_SUCCESS; +} + +/** + Set Redfish value with the given Schema and Configure Language. + + @param[in] This Pointer to EDKII_REDFISH_PLATFORM_CONFI= G_PROTOCOL instance. + @param[in] Schema The Redfish schema to query. + @param[in] Version The Redfish version to query. + @param[in] ConfigureLang The target value which match this confi= gure Language. + @param[in] Value The value to set. + + @retval EFI_SUCCESS Value is returned successfully. + @retval Others Some error happened. + +**/ +EFI_STATUS +EFIAPI +RedfishPlatformConfigProtocolSetValue ( + IN EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL *This, + IN CHAR8 *Schema, + IN CHAR8 *Version, + IN EFI_STRING ConfigureLang, + IN EDKII_REDFISH_VALUE Value + ) +{ + EFI_STATUS Status; + REDFISH_PLATFORM_CONFIG_PRIVATE *RedfishPlatformConfigPrivate; + CHAR8 *FullSchema; + HII_STATEMENT_VALUE NewValue; + + if (This =3D=3D NULL || IS_EMPTY_STRING (Schema) || IS_EMPTY_STRING (Ver= sion) || IS_EMPTY_STRING (ConfigureLang)) { + return EFI_INVALID_PARAMETER; + } + + if (Value.Type =3D=3D REDFISH_VALUE_TYPE_UNKNOWN || Value.Type >=3D REDF= ISH_VALUE_TYPE_MAX) { + return EFI_INVALID_PARAMETER; + } + + RedfishPlatformConfigPrivate =3D REDFISH_PLATFORM_CONFIG_PRIVATE_FROM_TH= IS (This); + FullSchema =3D NULL; + + FullSchema =3D GetFullSchemaString (Schema, Version); + if (FullSchema =3D=3D NULL) { + return EFI_OUT_OF_RESOURCES; + } + + ZeroMem (&NewValue, sizeof (HII_STATEMENT_VALUE)); + + switch (Value.Type) { + case REDFISH_VALUE_TYPE_INTEGER: + case REDFISH_VALUE_TYPE_BOOLEAN: + Status =3D RedfishNumericToHiiValue (&Value, &NewValue); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a, failed to convert Redfish value to Hii v= alue: %r\n", __FUNCTION__, Status)); + goto RELEASE_RESOURCE; + } + break; + case REDFISH_VALUE_TYPE_STRING: + NewValue.Type =3D EFI_IFR_TYPE_STRING; + NewValue.BufferLen =3D (UINT16)AsciiStrSize (Value.Value.Buffer); + NewValue.Buffer =3D AllocateCopyPool (NewValue.BufferLen, Value.Valu= e.Buffer); + if (NewValue.Buffer =3D=3D NULL) { + Status =3D EFI_OUT_OF_RESOURCES; + goto RELEASE_RESOURCE; + } + break; + case REDFISH_VALUE_TYPE_STRING_ARRAY: + NewValue.Type =3D EFI_IFR_TYPE_STRING; + NewValue.BufferLen =3D (UINT16)Value.ArrayCount; + NewValue.Buffer =3D (UINT8 *)Value.Value.StringArray; + break; + default: + ASSERT (FALSE); + break; + } + + Status =3D RedfishPlatformConfigSetStatementCommon (RedfishPlatformConfi= gPrivate, FullSchema, ConfigureLang, &NewValue); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a, failed to set value to statement: %r\n", __F= UNCTION__, Status)); + } + +RELEASE_RESOURCE: + + if (FullSchema !=3D NULL) { + FreePool (FullSchema); + } + + return Status; +} + +/** + Get the list of Configure Language from platform configuration by the gi= ven Schema and RegexPattern. + + @param[in] This Pointer to EDKII_REDFISH_PLATFORM_CONFI= G_PROTOCOL instance. + @param[in] Schema The Redfish schema to query. + @param[in] Version The Redfish version to query. + @param[in] RegexPattern The target Configure Language pattern. = This is used for regular expression matching. + @param[out] ConfigureLangList The list of Configure Language. + @param[out] Count The number of Configure Language in Con= figureLangList. + + @retval EFI_SUCCESS ConfigureLangList is returned successfu= lly. + @retval Others Some error happened. + +**/ +EFI_STATUS +EFIAPI +RedfishPlatformConfigProtocolGetConfigureLang ( + IN EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL *This, + IN CHAR8 *Schema, + IN CHAR8 *Version, + IN EFI_STRING RegexPattern, + OUT EFI_STRING **ConfigureLangList, + OUT UINTN *Count + ) +{ + REDFISH_PLATFORM_CONFIG_PRIVATE *RedfishPlatformConfigPr= ivate; + EFI_STATUS Status; + REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_LIST StatementList; + REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_REF *StatementRef; + LIST_ENTRY *NextLink; + EFI_STRING TmpString; + EFI_STRING *TmpConfigureLangList; + UINTN Index; + CHAR8 *FullSchema; + + if (This =3D=3D NULL || IS_EMPTY_STRING (Schema) || IS_EMPTY_STRING (Ver= sion) || Count =3D=3D NULL || ConfigureLangList =3D=3D NULL || IS_EMPTY_STR= ING (RegexPattern)) { + return EFI_INVALID_PARAMETER; + } + + *Count =3D 0; + *ConfigureLangList =3D NULL; + FullSchema =3D NULL; + RedfishPlatformConfigPrivate =3D REDFISH_PLATFORM_CONFIG_PRIVATE_FROM_TH= IS (This); + + Status =3D ProcessPendingList (&RedfishPlatformConfigPrivate->FormsetLis= t, &RedfishPlatformConfigPrivate->PendingList); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a, ProcessPendingList failure: %r\n", __FUNCTIO= N__, Status)); + return Status; + } + + FullSchema =3D GetFullSchemaString (Schema, Version); + if (FullSchema =3D=3D NULL) { + return EFI_OUT_OF_RESOURCES; + } + + Status =3D GetStatementPrivateByConfigureLangRegex ( + RedfishPlatformConfigPrivate->RegularExpressionProtocol, + &RedfishPlatformConfigPrivate->FormsetList, + FullSchema, + RegexPattern, + &StatementList + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a, GetStatementPrivateByConfigureLangRegex fail= ure: %r\n", __FUNCTION__, Status)); + goto RELEASE_RESOURCE; + } + + if (!IsListEmpty (&StatementList.StatementList)) { + + TmpConfigureLangList =3D AllocateZeroPool (sizeof (CHAR16 *) * Stateme= ntList.Count); + if (TmpConfigureLangList =3D=3D NULL) { + Status =3D EFI_OUT_OF_RESOURCES; + goto RELEASE_RESOURCE; + } + + Index =3D 0; + NextLink =3D GetFirstNode (&StatementList.StatementList); + while (!IsNull (&StatementList.StatementList, NextLink)) { + StatementRef =3D REDFISH_PLATFORM_CONFIG_STATEMENT_REF_FROM_LINK (Ne= xtLink); + NextLink =3D GetNextNode (&StatementList.StatementList, NextLink); + + ASSERT (StatementRef->Statement->Description !=3D 0); + if (StatementRef->Statement->Description !=3D 0) { + TmpString =3D HiiGetRedfishString (StatementRef->Statement->Parent= Form->ParentFormset->HiiHandle, FullSchema, StatementRef->Statement->Descri= ption); + ASSERT (TmpString !=3D NULL); + if (TmpString !=3D NULL) { + TmpConfigureLangList[Index] =3D AllocateCopyPool (StrSize (TmpSt= ring), TmpString); + ASSERT (TmpConfigureLangList[Index] !=3D NULL); + FreePool (TmpString); + ++Index; + } + } + } + } + + *Count =3D StatementList.Count; + *ConfigureLangList =3D TmpConfigureLangList; + +RELEASE_RESOURCE: + + if (FullSchema !=3D NULL) { + FreePool (FullSchema); + } + + ReleaseStatementList (&StatementList); + + return Status; +} + +/** + Get the list of supported Redfish schema from paltform configuration on = give HII handle. + + @param[in] This Pointer to EDKII_REDFISH_PLATFORM_CONFI= G_PROTOCOL instance. + @param[in] HiiHandle The target handle to search. If handle = is NULL, + this function return all schema from HI= I database. + @param[out] SupportedSchema The supported schema list which is sepa= rated by ';'. + The SupportedSchema is allocated by the= callee. It's caller's + responsibility to free this buffer usin= g FreePool(). + + @retval EFI_SUCCESS Schema is returned successfully. + @retval Others Some error happened. + +**/ +EFI_STATUS +EFIAPI +RedfishPlatformConfigProtocolGetSupportedSchema ( + IN EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL *This, + IN EFI_HII_HANDLE HiiHandle, OPTIONAL + OUT CHAR8 **SupportedSchema + ) +{ + REDFISH_PLATFORM_CONFIG_PRIVATE *RedfishPlatformConfigPrivate; + EFI_STATUS Status; + LIST_ENTRY *HiiFormsetLink; + LIST_ENTRY *HiiFormsetNextLink; + REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *HiiFormsetPrivate; + UINTN Index; + UINTN StringSize; + CHAR8 *StringBuffer; + UINTN StringIndex; + + if (This =3D=3D NULL || SupportedSchema =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + + *SupportedSchema =3D NULL; + + RedfishPlatformConfigPrivate =3D REDFISH_PLATFORM_CONFIG_PRIVATE_FROM_TH= IS (This); + + Status =3D ProcessPendingList (&RedfishPlatformConfigPrivate->FormsetLis= t, &RedfishPlatformConfigPrivate->PendingList); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a, ProcessPendingList failure: %r\n", __FUNCTIO= N__, Status)); + return Status; + } + + if (IsListEmpty (&RedfishPlatformConfigPrivate->FormsetList)) { + return EFI_NOT_FOUND; + } + + // + // Calculate for string buffer size. + // + StringSize =3D 0; + HiiFormsetLink =3D GetFirstNode (&RedfishPlatformConfigPrivate->FormsetL= ist); + while (!IsNull (&RedfishPlatformConfigPrivate->FormsetList, HiiFormsetLi= nk)) { + HiiFormsetNextLink =3D GetNextNode (&RedfishPlatformConfigPrivate->For= msetList, HiiFormsetLink); + HiiFormsetPrivate =3D REDFISH_PLATFORM_CONFIG_FORMSET_FROM_LINK (HiiFo= rmsetLink); + + if (HiiHandle !=3D NULL && HiiHandle !=3D HiiFormsetPrivate->HiiHandle= ) { + HiiFormsetLink =3D HiiFormsetNextLink; + continue; + } + + if (HiiFormsetPrivate->SupportedSchema.Count > 0) { + for (Index =3D 0; Index < HiiFormsetPrivate->SupportedSchema.Count; = Index++) { + StringSize +=3D AsciiStrSize (HiiFormsetPrivate->SupportedSchema.S= chemaList[Index]); + } + } + + HiiFormsetLink =3D HiiFormsetNextLink; + } + + if (StringSize =3D=3D 0) { + return EFI_NOT_FOUND; + } + + StringBuffer =3D AllocatePool (StringSize); + if (StringBuffer =3D=3D NULL) { + return EFI_OUT_OF_RESOURCES; + } + + StringIndex =3D 0; + HiiFormsetLink =3D GetFirstNode (&RedfishPlatformConfigPrivate->FormsetL= ist); + while (!IsNull (&RedfishPlatformConfigPrivate->FormsetList, HiiFormsetLi= nk)) { + HiiFormsetNextLink =3D GetNextNode (&RedfishPlatformConfigPrivate->For= msetList, HiiFormsetLink); + HiiFormsetPrivate =3D REDFISH_PLATFORM_CONFIG_FORMSET_FROM_LINK (HiiFo= rmsetLink); + + if (HiiHandle !=3D NULL && HiiHandle !=3D HiiFormsetPrivate->HiiHandle= ) { + HiiFormsetLink =3D HiiFormsetNextLink; + continue; + } + + if (HiiFormsetPrivate->SupportedSchema.Count > 0) { + for (Index =3D 0; Index < HiiFormsetPrivate->SupportedSchema.Count; = Index++) { + AsciiStrCpyS (&StringBuffer[StringIndex], (StringSize - StringInde= x), HiiFormsetPrivate->SupportedSchema.SchemaList[Index]); + StringIndex +=3D AsciiStrLen (HiiFormsetPrivate->SupportedSchema.S= chemaList[Index]); + StringBuffer[StringIndex] =3D ';'; + ++StringIndex; + } + } + + HiiFormsetLink =3D HiiFormsetNextLink; + } + + StringBuffer[--StringIndex] =3D '\0'; + + *SupportedSchema =3D StringBuffer; + + return EFI_SUCCESS; +} + +/** + Functions which are registered to receive notification of + database events have this prototype. The actual event is encoded + in NotifyType. The following table describes how PackageType, + PackageGuid, Handle, and Package are used for each of the + notification types. + + @param[in] PackageType Package type of the notification. + @param[in] PackageGuid If PackageType is + EFI_HII_PACKAGE_TYPE_GUID, then this is + the pointer to the GUID from the Guid + field of EFI_HII_PACKAGE_GUID_HEADER. + Otherwise, it must be NULL. + @param[in] Package Points to the package referred to by the + notification Handle The handle of the package + list which contains the specified package. + @param[in] Handle The HII handle. + @param[in] NotifyType The type of change concerning the + database. See + EFI_HII_DATABASE_NOTIFY_TYPE. + +**/ +EFI_STATUS +EFIAPI +RedfishPlatformConfigFormUpdateNotify ( + IN UINT8 PackageType, + IN CONST EFI_GUID *PackageGuid, + IN CONST EFI_HII_PACKAGE_HEADER *Package, + IN EFI_HII_HANDLE Handle, + IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType + ) +{ + EFI_STATUS Status; + + if (NotifyType =3D=3D EFI_HII_DATABASE_NOTIFY_NEW_PACK || NotifyType =3D= =3D EFI_HII_DATABASE_NOTIFY_ADD_PACK) { + // + // HII formset on this handle is updated by driver during run-time. Th= e formset needs to be reloaded. + // + Status =3D NotifyFormsetUpdate (Handle, &mRedfishPlatformConfigPrivate= ->PendingList); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a, failed to notify updated formset of HII ha= ndle: 0x%x\n", __FUNCTION__, Handle)); + return Status; + } + } else if (NotifyType =3D=3D EFI_HII_DATABASE_NOTIFY_REMOVE_PACK) { + // + // HII resource is removed. The formset is no longer exist. + // + Status =3D NotifyFormsetDeleted (Handle, &mRedfishPlatformConfigPrivat= e->PendingList); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a, failed to notify deleted formset of HII ha= ndle: 0x%x\n", __FUNCTION__, Handle)); + return Status; + } + } + + return EFI_SUCCESS; +} + +/** + This is a EFI_HII_STRING_PROTOCOL notification event handler. + + Install HII package notification. + + @param[in] Event Event whose notification function is being invoked. + @param[in] Context Pointer to the notification function's context. + +**/ +VOID +EFIAPI +HiiStringProtocolInstalled ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + EFI_STATUS Status; + + // + // Locate HII database protocol. + // + Status =3D gBS->LocateProtocol ( + &gEfiHiiStringProtocolGuid, + NULL, + (VOID **)&mRedfishPlatformConfigPrivate->HiiString + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a, locate EFI_HII_STRING_PROTOCOL failure: %r\n= ", __FUNCTION__, Status)); + return; + } + + gBS->CloseEvent (Event); + mRedfishPlatformConfigPrivate->HiiStringNotify.ProtocolEvent =3D NULL; +} + +/** + This is a EFI_HII_DATABASE_PROTOCOL notification event handler. + + Install HII package notification. + + @param[in] Event Event whose notification function is being invoked. + @param[in] Context Pointer to the notification function's context. + +**/ +VOID +EFIAPI +HiiDatabaseProtocolInstalled ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + EFI_STATUS Status; + + // + // Locate HII database protocol. + // + Status =3D gBS->LocateProtocol ( + &gEfiHiiDatabaseProtocolGuid, + NULL, + (VOID **)&mRedfishPlatformConfigPrivate->HiiDatabase + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a, locate EFI_HII_DATABASE_PROTOCOL failure: %r= \n", __FUNCTION__, Status)); + return; + } + + // + // Register package notification when new form package is installed. + // + Status =3D mRedfishPlatformConfigPrivate->HiiDatabase->RegisterPackageNo= tify ( + mRedfishPlatformConfigPrivate= ->HiiDatabase, + EFI_HII_PACKAGE_FORMS, + NULL, + RedfishPlatformConfigFormUpda= teNotify, + EFI_HII_DATABASE_NOTIFY_NEW_P= ACK, + &mRedfishPlatformConfigPrivat= e->NotifyHandle + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a, RegisterPackageNotify for EFI_HII_DATABASE_N= OTIFY_NEW_PACK failure: %r\n", __FUNCTION__, Status)); + } + + // + // Register package notification when new form package is updated. + // + Status =3D mRedfishPlatformConfigPrivate->HiiDatabase->RegisterPackageNo= tify ( + mRedfishPlatformConfigPrivate= ->HiiDatabase, + EFI_HII_PACKAGE_FORMS, + NULL, + RedfishPlatformConfigFormUpda= teNotify, + EFI_HII_DATABASE_NOTIFY_ADD_P= ACK, + &mRedfishPlatformConfigPrivat= e->NotifyHandle + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a, RegisterPackageNotify for EFI_HII_DATABASE_N= OTIFY_NEW_PACK failure: %r\n", __FUNCTION__, Status)); + } + + gBS->CloseEvent (Event); + mRedfishPlatformConfigPrivate->HiiDbNotify.ProtocolEvent =3D NULL; + +} + +/** + This is a EFI_REGULAR_EXPRESSION_PROTOCOL notification event handler. + + @param[in] Event Event whose notification function is being invoked. + @param[in] Context Pointer to the notification function's context. + +**/ +VOID +EFIAPI +RegexProtocolInstalled ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + EFI_STATUS Status; + + // + // Locate regular expression protocol. + // + Status =3D gBS->LocateProtocol ( + &gEfiRegularExpressionProtocolGuid, + NULL, + (VOID **)&mRedfishPlatformConfigPrivate->RegularExpressi= onProtocol + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a, locate EFI_REGULAR_EXPRESSION_PROTOCOL failu= re: %r\n", __FUNCTION__, Status)); + return; + } + + gBS->CloseEvent (Event); + mRedfishPlatformConfigPrivate->RegexNotify.ProtocolEvent =3D NULL; + +} + +/** + Unloads an image. + + @param ImageHandle Handle that identifies the image to be unl= oaded. + + @retval EFI_SUCCESS The image has been unloaded. + @retval EFI_INVALID_PARAMETER ImageHandle is not a valid image handle. + +**/ +EFI_STATUS +EFIAPI +RedfishPlatformConfigDxeUnload ( + IN EFI_HANDLE ImageHandle + ) +{ + EFI_STATUS Status; + + if (mRedfishPlatformConfigPrivate !=3D NULL) { + Status =3D gBS->UninstallProtocolInterface ( + mRedfishPlatformConfigPrivate->ImageHandle, + &gEdkIIRedfishPlatformConfigProtocolGuid, + (VOID*)&mRedfishPlatformConfigPrivate->Protocol + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a, can not uninstall gEdkIIRedfishPlatformCon= figProtocolGuid: %r\n", __FUNCTION__, Status)); + ASSERT (FALSE); + } + + // + // Close events + // + if (mRedfishPlatformConfigPrivate->HiiDbNotify.ProtocolEvent !=3D NULL= ) { + gBS->CloseEvent (mRedfishPlatformConfigPrivate->HiiDbNotify.Protocol= Event); + } + if (mRedfishPlatformConfigPrivate->HiiStringNotify.ProtocolEvent !=3D = NULL) { + gBS->CloseEvent (mRedfishPlatformConfigPrivate->HiiStringNotify.Prot= ocolEvent); + } + if (mRedfishPlatformConfigPrivate->RegexNotify.ProtocolEvent !=3D NULL= ) { + gBS->CloseEvent (mRedfishPlatformConfigPrivate->RegexNotify.Protocol= Event); + } + + // + // Unregister package notification. + // + if (mRedfishPlatformConfigPrivate->NotifyHandle !=3D NULL) { + mRedfishPlatformConfigPrivate->HiiDatabase->UnregisterPackageNotify ( + mRedfishPlatformConfigPrivate->H= iiDatabase, + mRedfishPlatformConfigPrivate->N= otifyHandle + ); + } + + ReleaseFormsetList (&mRedfishPlatformConfigPrivate->FormsetList); + FreePool (mRedfishPlatformConfigPrivate); + mRedfishPlatformConfigPrivate =3D NULL; + } + + return EFI_SUCCESS; +} + +/** + 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 includ= ing + both device drivers and bus drivers. + + @param ImageHandle The firmware allocated handle for the UEFI= image. + @param SystemTable A pointer to the EFI System Table. + + @retval EFI_SUCCESS The operation completed successfully. + @retval Others An unexpected error occurred. +**/ +EFI_STATUS +EFIAPI +RedfishPlatformConfigDxeEntryPoint ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + + mRedfishPlatformConfigPrivate =3D (REDFISH_PLATFORM_CONFIG_PRIVATE *)All= ocateZeroPool (sizeof (REDFISH_PLATFORM_CONFIG_PRIVATE)); + if (mRedfishPlatformConfigPrivate =3D=3D NULL) { + DEBUG ((DEBUG_ERROR, "%a, can not allocate pool for REDFISH_PLATFORM_C= ONFIG_PRIVATE\n", __FUNCTION__)); + ASSERT (FALSE); + return EFI_OUT_OF_RESOURCES; + } + + // + // Protocol initialization + // + mRedfishPlatformConfigPrivate->ImageHandle =3D ImageHandle; + mRedfishPlatformConfigPrivate->Protocol.GetValue =3D RedfishPlatformConf= igProtocolGetValue; + mRedfishPlatformConfigPrivate->Protocol.SetValue =3D RedfishPlatformConf= igProtocolSetValue; + mRedfishPlatformConfigPrivate->Protocol.GetConfigureLang =3D RedfishPlat= formConfigProtocolGetConfigureLang; + mRedfishPlatformConfigPrivate->Protocol.GetSupportedSchema =3D RedfishPl= atformConfigProtocolGetSupportedSchema; + + InitializeListHead (&mRedfishPlatformConfigPrivate->FormsetList); + InitializeListHead (&mRedfishPlatformConfigPrivate->PendingList); + + Status =3D gBS->InstallProtocolInterface ( + &ImageHandle, + &gEdkIIRedfishPlatformConfigProtocolGuid, + EFI_NATIVE_INTERFACE, + (VOID*)&mRedfishPlatformConfigPrivate->Protocol + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a, can not install gEdkIIRedfishPlatformConfigP= rotocolGuid: %r\n", __FUNCTION__, Status)); + ASSERT (FALSE); + } + + // + // Install protocol notification if HII database protocol is installed. + // + mRedfishPlatformConfigPrivate->HiiDbNotify.ProtocolEvent =3D EfiCreatePr= otocolNotifyEvent ( + &gEfiHiiData= baseProtocolGuid, + TPL_CALLBACK, + HiiDatabaseP= rotocolInstalled, + NULL, + &mRedfishPla= tformConfigPrivate->HiiDbNotify.Registration + ); + if (mRedfishPlatformConfigPrivate->HiiDbNotify.ProtocolEvent =3D=3D NULL= ) { + DEBUG ((DEBUG_ERROR, "%a, failed to create protocol notification for g= EfiHiiDatabaseProtocolGuid\n", __FUNCTION__)); + ASSERT (FALSE); + } + + // + // Install protocol notification if HII string protocol is installed. + // + mRedfishPlatformConfigPrivate->HiiStringNotify.ProtocolEvent =3D EfiCrea= teProtocolNotifyEvent ( + &gEfiHii= StringProtocolGuid, + TPL_CALL= BACK, + HiiStrin= gProtocolInstalled, + NULL, + &mRedfis= hPlatformConfigPrivate->HiiStringNotify.Registration + ); + if (mRedfishPlatformConfigPrivate->HiiStringNotify.ProtocolEvent =3D=3D = NULL) { + DEBUG ((DEBUG_ERROR, "%a, failed to create protocol notification for g= EfiHiiStringProtocolGuid\n", __FUNCTION__)); + ASSERT (FALSE); + } + + // + // Install protocol notification if regular expression protocol is insta= lled. + // + mRedfishPlatformConfigPrivate->RegexNotify.ProtocolEvent =3D EfiCreatePr= otocolNotifyEvent ( + &gEfiRegular= ExpressionProtocolGuid, + TPL_CALLBACK, + RegexProtoco= lInstalled, + NULL, + &mRedfishPla= tformConfigPrivate->RegexNotify.Registration + ); + if (mRedfishPlatformConfigPrivate->RegexNotify.ProtocolEvent =3D=3D NULL= ) { + DEBUG ((DEBUG_ERROR, "%a, failed to create protocol notification for g= EfiRegularExpressionProtocolGuid\n", __FUNCTION__)); + ASSERT (FALSE); + } + + return EFI_SUCCESS; +} diff --git a/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.h= b/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.h index 99a613d229..d3f7af55ad 100644 --- a/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.h +++ b/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.h @@ -1,64 +1,64 @@ -/** @file - This file defines the EDKII Redfish Platform Config Protocol interface. - - (C) Copyright 2021 Hewlett Packard Enterprise Development LP
- - SPDX-License-Identifier: BSD-2-Clause-Patent - -**/ - -#ifndef EDKII_REDFISH_PLATFORM_CONFIG_DXE_H_ -#define EDKII_REDFISH_PLATFORM_CONFIG_DXE_H_ - -#include - -// -// Libraries -// -#include -#include -#include -#include -#include -#include -#include -#include - -// -// Produced Protocols -// -#include -#include -#include -#include - -// -// Definition of EDKII_REDFISH_PLATFORM_CONFIG_NOTIFY. -// -typedef struct { - EFI_EVENT ProtocolEvent; // Protocol notification ev= ent. - VOID *Registration; // Protocol notification re= gistration. -} REDFISH_PLATFORM_CONFIG_NOTIFY; - -// -// Definition of REDFISH_PLATFORM_CONFIG_PRIVATE. -// -typedef struct { - EFI_HANDLE ImageHandle; //= Driver image handle. - EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL Protocol; - REDFISH_PLATFORM_CONFIG_NOTIFY HiiDbNotify; - EFI_HII_DATABASE_PROTOCOL *HiiDatabase; //= The HII database protocol. - REDFISH_PLATFORM_CONFIG_NOTIFY HiiStringNotify; - EFI_HII_STRING_PROTOCOL *HiiString; //= HII String Protocol. - REDFISH_PLATFORM_CONFIG_NOTIFY RegexNotify; - EFI_REGULAR_EXPRESSION_PROTOCOL *RegularExpressionProtocol; //= Regular Expression Protocol. - EFI_HANDLE NotifyHandle; //= The notify handle. - LIST_ENTRY FormsetList; //= The list to keep cached HII formset. - LIST_ENTRY PendingList; //= The list to keep updated HII handle. -} REDFISH_PLATFORM_CONFIG_PRIVATE; - -#define REDFISH_PLATFORM_CONFIG_PRIVATE_FROM_THIS(a) BASE_CR (a, REDFISH_= PLATFORM_CONFIG_PRIVATE, Protocol) -#define REGULAR_EXPRESSION_INCLUDE_ALL L".*" -#define CONFIGURE_LANGUAGE_PREFIX "x-uefi-redfish-" - -#endif +/** @file + This file defines the EDKII Redfish Platform Config Protocol interface. + + (C) Copyright 2021 Hewlett Packard Enterprise Development LP
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef EDKII_REDFISH_PLATFORM_CONFIG_DXE_H_ +#define EDKII_REDFISH_PLATFORM_CONFIG_DXE_H_ + +#include + +// +// Libraries +// +#include +#include +#include +#include +#include +#include +#include +#include + +// +// Produced Protocols +// +#include +#include +#include +#include + +// +// Definition of EDKII_REDFISH_PLATFORM_CONFIG_NOTIFY. +// +typedef struct { + EFI_EVENT ProtocolEvent; // Protocol notification ev= ent. + VOID *Registration; // Protocol notification re= gistration. +} REDFISH_PLATFORM_CONFIG_NOTIFY; + +// +// Definition of REDFISH_PLATFORM_CONFIG_PRIVATE. +// +typedef struct { + EFI_HANDLE ImageHandle; //= Driver image handle. + EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL Protocol; + REDFISH_PLATFORM_CONFIG_NOTIFY HiiDbNotify; + EFI_HII_DATABASE_PROTOCOL *HiiDatabase; //= The HII database protocol. + REDFISH_PLATFORM_CONFIG_NOTIFY HiiStringNotify; + EFI_HII_STRING_PROTOCOL *HiiString; //= HII String Protocol. + REDFISH_PLATFORM_CONFIG_NOTIFY RegexNotify; + EFI_REGULAR_EXPRESSION_PROTOCOL *RegularExpressionProtocol; //= Regular Expression Protocol. + EFI_HANDLE NotifyHandle; //= The notify handle. + LIST_ENTRY FormsetList; //= The list to keep cached HII formset. + LIST_ENTRY PendingList; //= The list to keep updated HII handle. +} REDFISH_PLATFORM_CONFIG_PRIVATE; + +#define REDFISH_PLATFORM_CONFIG_PRIVATE_FROM_THIS(a) BASE_CR (a, REDFISH_= PLATFORM_CONFIG_PRIVATE, Protocol) +#define REGULAR_EXPRESSION_INCLUDE_ALL L".*" +#define CONFIGURE_LANGUAGE_PREFIX "x-uefi-redfish-" + +#endif diff --git a/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.i= nf b/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.inf index 16739bef7a..81b22e03c3 100644 --- a/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.inf +++ b/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.inf @@ -1,53 +1,53 @@ -## @file -# Implementation of EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL interfaces. -# -# (C) Copyright 2021 Hewlett Packard Enterprise Development LP
-# SPDX-License-Identifier: BSD-2-Clause-Patent -# -## - -[Defines] - INF_VERSION =3D 0x00010005 - BASE_NAME =3D RedfishPlatformConfigDxe - FILE_GUID =3D BEAEFFE1-0633-41B5-913C-9389339C2927 - MODULE_TYPE =3D DXE_DRIVER - VERSION_STRING =3D 1.0 - ENTRY_POINT =3D RedfishPlatformConfigDxeEntryPoint - UNLOAD_IMAGE =3D RedfishPlatformConfigDxeUnload - -[Packages] - MdePkg/MdePkg.dec - MdeModulePkg/MdeModulePkg.dec - RedfishPkg/RedfishPkg.dec - -[Sources] - RedfishPlatformConfigDxe.h - RedfishPlatformConfigDxe.c - RedfishPlatformConfigImpl.h - RedfishPlatformConfigImpl.c - -[LibraryClasses] - BaseLib - BaseMemoryLib - DebugLib - DevicePathLib - HiiLib - HiiUtilityLib - MemoryAllocationLib - PrintLib - UefiLib - UefiBootServicesTableLib - UefiRuntimeServicesTableLib - UefiDriverEntryPoint - -[Protocols] - gEdkIIRedfishPlatformConfigProtocolGuid ## PRODUCED - gEfiHiiDatabaseProtocolGuid ## CONSUMED - gEfiHiiStringProtocolGuid ## CONSUMED - gEfiRegularExpressionProtocolGuid ## CONSUMED - -[Guids] - gEfiRegexSyntaxTypePerlGuid ## CONSUMED - -[Depex] +## @file +# Implementation of EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL interfaces. +# +# (C) Copyright 2021 Hewlett Packard Enterprise Development LP
+# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION =3D 0x00010005 + BASE_NAME =3D RedfishPlatformConfigDxe + FILE_GUID =3D BEAEFFE1-0633-41B5-913C-9389339C2927 + MODULE_TYPE =3D DXE_DRIVER + VERSION_STRING =3D 1.0 + ENTRY_POINT =3D RedfishPlatformConfigDxeEntryPoint + UNLOAD_IMAGE =3D RedfishPlatformConfigDxeUnload + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + RedfishPkg/RedfishPkg.dec + +[Sources] + RedfishPlatformConfigDxe.h + RedfishPlatformConfigDxe.c + RedfishPlatformConfigImpl.h + RedfishPlatformConfigImpl.c + +[LibraryClasses] + BaseLib + BaseMemoryLib + DebugLib + DevicePathLib + HiiLib + HiiUtilityLib + MemoryAllocationLib + PrintLib + UefiLib + UefiBootServicesTableLib + UefiRuntimeServicesTableLib + UefiDriverEntryPoint + +[Protocols] + gEdkIIRedfishPlatformConfigProtocolGuid ## PRODUCED + gEfiHiiDatabaseProtocolGuid ## CONSUMED + gEfiHiiStringProtocolGuid ## CONSUMED + gEfiRegularExpressionProtocolGuid ## CONSUMED + +[Guids] + gEfiRegexSyntaxTypePerlGuid ## CONSUMED + +[Depex] TRUE \ No newline at end of file diff --git a/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigImpl.= c b/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigImpl.c index d9eab6c883..525e666b6c 100644 --- a/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigImpl.c +++ b/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigImpl.c @@ -1,1240 +1,1288 @@ -/** @file - - The implementation of EDKII Redfidh Platform Config Protocol. - - (C) Copyright 2021 Hewlett Packard Enterprise Development LP
- - SPDX-License-Identifier: BSD-2-Clause-Patent - -**/ -#include "RedfishPlatformConfigDxe.h" -#include "RedfishPlatformConfigImpl.h" - -extern REDFISH_PLATFORM_CONFIG_PRIVATE *mRedfishPlatformConfigPrivate; - -/** - Debug dump HII string - - @param[in] HiiHandle HII handle instance - @param[in] StringId HII string to dump - - @retval EFI_SUCCESS Dump HII string successfully - @retval Others Errors occur - -**/ -EFI_STATUS -DumpHiiString ( - IN EFI_HII_HANDLE HiiHandle, - IN EFI_STRING_ID StringId - ) -{ - EFI_STRING String; - - if (HiiHandle =3D=3D NULL || StringId =3D=3D 0) { - DEBUG ((DEBUG_INFO, "???")); - return EFI_INVALID_PARAMETER; - } - - String =3D HiiGetString (HiiHandle, StringId, NULL); - if (String =3D=3D NULL) { - return EFI_NOT_FOUND; - } - - DEBUG ((DEBUG_INFO, "%s", String)); - FreePool (String); - - return EFI_SUCCESS; -} - -/** - Debug dump HII form-set data - - @param[in] FormsetPrivate HII form-set private instance. - - @retval EFI_SUCCESS Dump form-set successfully - @retval Others Errors occur - -**/ -EFI_STATUS -DumpFormset ( - IN REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *FormsetPrivate - ) -{ - LIST_ENTRY *HiiFormLink; - LIST_ENTRY *HiiNextFormLink; - REDFISH_PLATFORM_CONFIG_FORM_PRIVATE *HiiFormPrivate; - LIST_ENTRY *HiiStatementLink; - LIST_ENTRY *HiiNextStatementLink; - REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE *HiiStatementPrivate; - UINTN Index; - - if (FormsetPrivate =3D=3D NULL) { - return EFI_INVALID_PARAMETER; - } - - Index =3D 0; - HiiFormLink =3D GetFirstNode (&FormsetPrivate->HiiFormList); - while (!IsNull (&FormsetPrivate->HiiFormList, HiiFormLink)) { - HiiFormPrivate =3D REDFISH_PLATFORM_CONFIG_FORM_FROM_LINK (HiiFormLink= ); - HiiNextFormLink =3D GetNextNode (&FormsetPrivate->HiiFormList, HiiForm= Link); - - DEBUG ((DEBUG_INFO, " [%d] form: %d title: ", ++Index, HiiFormPrivate= ->Id)); - DumpHiiString (FormsetPrivate->HiiHandle, HiiFormPrivate->Title); - DEBUG ((DEBUG_INFO, "\n")); - - HiiStatementLink =3D GetFirstNode (&HiiFormPrivate->StatementList); - while (!IsNull (&HiiFormPrivate->StatementList, HiiStatementLink)) { - HiiStatementPrivate =3D REDFISH_PLATFORM_CONFIG_STATEMENT_FROM_LINK = (HiiStatementLink); - HiiNextStatementLink =3D GetNextNode (&HiiFormPrivate->StatementList= , HiiStatementLink); - - DEBUG ((DEBUG_INFO, " QID: 0x%x Prompt: ", HiiStatementPrivate->Q= uestionId)); - DumpHiiString (FormsetPrivate->HiiHandle, HiiStatementPrivate->Descr= iption); - DEBUG ((DEBUG_INFO, "\n")); - - HiiStatementLink =3D HiiNextStatementLink; - } - - HiiFormLink =3D HiiNextFormLink; - } - - return EFI_SUCCESS; -} - -/** - Debug dump HII form-set list - - @param[in] FormsetList Form-set list instance - - @retval EFI_SUCCESS Dump list successfully - @retval Others Errors occur - -**/ -EFI_STATUS -DumpFormsetList ( - IN LIST_ENTRY *FormsetList - ) -{ - LIST_ENTRY *HiiFormsetLink; - LIST_ENTRY *HiiFormsetNextLink; - REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *HiiFormsetPrivate; - UINTN Index; - - if (FormsetList =3D=3D NULL) { - return EFI_INVALID_PARAMETER; - } - - if (IsListEmpty (FormsetList)) { - DEBUG ((DEBUG_INFO, "%a, Empty formset list\n", __FUNCTION__)); - return EFI_SUCCESS; - } - - Index =3D 0; - HiiFormsetLink =3D GetFirstNode (FormsetList); - while (!IsNull (FormsetList, HiiFormsetLink)) { - HiiFormsetNextLink =3D GetNextNode (FormsetList, HiiFormsetLink); - HiiFormsetPrivate =3D REDFISH_PLATFORM_CONFIG_FORMSET_FROM_LINK (HiiFo= rmsetLink); - - DEBUG ((DEBUG_INFO, "[%d] HII Handle: 0x%x formset: %g at %s\n", ++Ind= ex, HiiFormsetPrivate->HiiHandle, &HiiFormsetPrivate->Guid, HiiFormsetPriva= te->DevicePathStr)); - DumpFormset (HiiFormsetPrivate); - - HiiFormsetLink =3D HiiFormsetNextLink; - } - - return EFI_SUCCESS; -} - -/** - Retrieves a string from a string package in a English language. The - returned string is allocated using AllocatePool(). The caller is respon= sible - for freeing the allocated buffer using FreePool(). - - If HiiHandle is NULL, then ASSERT(). - If StringId is 0, then ASSET. - - @param[in] HiiStringProtocol EFI_HII_STRING_PROTOCOL instance. - @param[in] HiiHandle A handle that was previously registered in= the HII Database. - @param[in] StringId The identifier of the string to retrieved = from the string - package associated with HiiHandle. - - @retval NULL The string specified by StringId is not present in the st= ring package. - @retval Other The string was returned. - -**/ -EFI_STRING -HiiGetRedfishString ( - IN EFI_HII_HANDLE HiiHandle, - IN CHAR8 *Language, - IN EFI_STRING_ID StringId - ) -{ - EFI_STATUS Status; - UINTN StringSize; - CHAR16 TempString; - EFI_STRING String; - - if (mRedfishPlatformConfigPrivate->HiiString =3D=3D NULL || HiiHandle = =3D=3D NULL || StringId =3D=3D 0 || IS_EMPTY_STRING (Language)) { - ASSERT (FALSE); - return NULL; - } - - // - // Retrieve the size of the string in the string package for the BestLan= guage - // - StringSize =3D 0; - Status =3D mRedfishPlatformConfigPrivate->HiiString->GetString ( - mRedfishPlatformConfigPrivate= ->HiiString, - Language, - HiiHandle, - StringId, - &TempString, - &StringSize, - NULL - ); - // - // If GetString() returns EFI_SUCCESS for a zero size, - // then there are no supported languages registered for HiiHandle. If G= etString() - // returns an error other than EFI_BUFFER_TOO_SMALL, then HiiHandle is n= ot present - // in the HII Database - // - if (Status !=3D EFI_BUFFER_TOO_SMALL) { - return NULL; - } - - // - // Allocate a buffer for the return string - // - String =3D AllocateZeroPool (StringSize); - if (String =3D=3D NULL) { - return NULL; - } - - // - // Retrieve the string from the string package - // - Status =3D mRedfishPlatformConfigPrivate->HiiString->GetString ( - mRedfishPlatformConfigPrivate= ->HiiString, - Language, - HiiHandle, - StringId, - String, - &StringSize, - NULL - ); - if (EFI_ERROR (Status)) { - // - // Free the buffer and return NULL if the supported languages can not = be retrieved. - // - FreePool (String); - String =3D NULL; - } - - // - // Return the Null-terminated Unicode string - // - return String; -} - -/** - Get string from HII database in English language. - - @param[in] HiiHandle A handle that was previously registered in= the HII Database. - @param[in] StringId The identifier of the string to retrieved = from the string - package associated with HiiHandle. - - @retval NULL The string specified by StringId is not present in the st= ring package. - @retval Other The string was returned. - -**/ -EFI_STRING -HiiGetEnglishString ( - IN EFI_HII_HANDLE HiiHandle, - IN EFI_STRING_ID StringId - ) -{ - return HiiGetRedfishString (HiiHandle, ENGLISH_LANGUAGE_CODE, StringId); -} - -/** - Check and see if this is supported schema or not. - - @param[in] SupportedSchema The list of supported schema. - @param[in] Schema Schema string to be checked. - - @retval BOOLEAN TRUE if this is supported schema. FALSE ot= herwise. - -**/ -BOOLEAN -CheckSupportedSchema ( - IN REDFISH_PLATFORM_CONFIG_SCHEMA *SupportedSchema, - IN CHAR8 *Schema - ) -{ - UINTN Index; - - if (SupportedSchema =3D=3D NULL || IS_EMPTY_STRING (Schema)) { - return FALSE; - } - - if (SupportedSchema->Count =3D=3D 0) { - return FALSE; - } - - for (Index =3D 0; Index < SupportedSchema->Count; Index++) { - if (AsciiStrCmp (SupportedSchema->SchemaList[Index], Schema) =3D=3D 0)= { - return TRUE; - } - } - - return FALSE; -} - -/** - Get the list of supported schema from the given HII handle. - - @param[in] HiiHandle HII handle instance. - @param[out] SupportedSchema Supported schema on this HII handle. - - @retval EFI_SUCCESS Schema list is returned. - @retval EFI_INVALID_PARAMETER HiiHandle is NULL or SupportedSchema is NU= LL. - @retval EFI_NOT_FOUND No supported schema found. - @retval EFI_OUT_OF_RESOURCES System is out of memory. - -**/ -EFI_STATUS -GetSupportedSchema ( - IN EFI_HII_HANDLE HiiHandle, - OUT REDFISH_PLATFORM_CONFIG_SCHEMA *SupportedSchema - ) -{ - CHAR8 *SupportedLanguages; - UINTN Index; - UINTN LangIndex; - UINTN Count; - UINTN StrSize; - UINTN ListIndex; - - if (HiiHandle =3D=3D NULL || SupportedSchema =3D=3D NULL) { - return EFI_INVALID_PARAMETER; - } - - SupportedSchema->Count =3D 0; - - SupportedLanguages =3D HiiGetSupportedLanguages (HiiHandle); - if (SupportedLanguages =3D=3D NULL) { - return EFI_NOT_FOUND; - } - - Index =3D 0; - LangIndex =3D 0; - Count =3D 0; - while (TRUE) { - if (SupportedLanguages[Index] =3D=3D ';' || SupportedLanguages[Index] = =3D=3D '\0') { - if (AsciiStrnCmp (&SupportedLanguages[LangIndex], X_UEFI_SCHEMA_PREF= IX, AsciiStrLen (X_UEFI_SCHEMA_PREFIX)) =3D=3D 0) { - ++Count; - } - LangIndex =3D Index + 1; - } - - if (SupportedLanguages[Index] =3D=3D '\0') { - break; - } - - ++Index; - } - - if (Count =3D=3D 0) { - return EFI_NOT_FOUND; - } - - SupportedSchema->Count =3D Count; - SupportedSchema->SchemaList =3D AllocatePool (sizeof (CHAR8 *) * Count); - if (SupportedSchema->SchemaList =3D=3D NULL) { - return EFI_OUT_OF_RESOURCES; - } - - Index =3D 0; - LangIndex =3D 0; - ListIndex =3D 0; - while (TRUE) { - - if (SupportedLanguages[Index] =3D=3D ';' || SupportedLanguages[Index] = =3D=3D '\0') { - if (AsciiStrnCmp (&SupportedLanguages[LangIndex], X_UEFI_SCHEMA_PREF= IX, AsciiStrLen (X_UEFI_SCHEMA_PREFIX)) =3D=3D 0) { - StrSize =3D Index - LangIndex; - SupportedSchema->SchemaList[ListIndex] =3D AllocateCopyPool ((StrS= ize + 1), &SupportedLanguages[LangIndex]); - SupportedSchema->SchemaList[ListIndex][StrSize] =3D '\0'; - ++ListIndex; - } - - LangIndex =3D Index + 1; - } - - if (SupportedLanguages[Index] =3D=3D '\0') { - break; - } - - ++Index; - } - - return EFI_SUCCESS; -} - -/** - Search and find statement private instance by given regular expression p= atthern - which describes the Configure Language. - - @param[in] RegularExpressionProtocol Regular express protocol. - @param[in] FormsetList Form-set list to search. - @param[in] Schema Schema to be matched. - @param[in] Pattern Regular expression pattern. - @param[out] StatementList Statement list that match above = pattern. - - @retval EFI_SUCCESS Statement list is returned. - @retval EFI_INVALID_PARAMETER Input parameter is NULL. - @retval EFI_NOT_READY Regular express protocol is NULL. - @retval EFI_NOT_FOUND No statement is found. - @retval EFI_OUT_OF_RESOURCES System is out of memory. - -**/ -EFI_STATUS -GetStatementPrivateByConfigureLangRegex ( - IN EFI_REGULAR_EXPRESSION_PROTOCOL *RegularExpressionPr= otocol, - IN LIST_ENTRY *FormsetList, - IN CHAR8 *Schema, - IN EFI_STRING Pattern, - OUT REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_LIST *StatementList - ) -{ - LIST_ENTRY *HiiFormsetLink; - LIST_ENTRY *HiiFormsetNextLink; - REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *HiiFormsetPrivate; - LIST_ENTRY *HiiFormLink; - LIST_ENTRY *HiiNextFormLink; - REDFISH_PLATFORM_CONFIG_FORM_PRIVATE *HiiFormPrivate; - LIST_ENTRY *HiiStatementLink; - LIST_ENTRY *HiiNextStatementLink; - REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE *HiiStatementPrivate; - EFI_STRING TmpString; - UINTN CaptureCount; - BOOLEAN IsMatch; - EFI_STATUS Status; - REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_REF *StatementRef; - - if (FormsetList =3D=3D NULL || IS_EMPTY_STRING (Schema) || IS_EMPTY_STRI= NG (Pattern) || StatementList =3D=3D NULL) { - return EFI_INVALID_PARAMETER; - } - - if (RegularExpressionProtocol =3D=3D NULL) { - return EFI_NOT_READY; - } - - StatementList->Count =3D 0; - InitializeListHead (&StatementList->StatementList); - - if (IsListEmpty (FormsetList)) { - return EFI_NOT_FOUND; - } - - HiiFormsetLink =3D GetFirstNode (FormsetList); - while (!IsNull (FormsetList, HiiFormsetLink)) { - HiiFormsetNextLink =3D GetNextNode (FormsetList, HiiFormsetLink); - HiiFormsetPrivate =3D REDFISH_PLATFORM_CONFIG_FORMSET_FROM_LINK (HiiFo= rmsetLink); - - // - // Performance check. - // If there is no desired Redfish schema found, skip this formset. - // - if (!CheckSupportedSchema (&HiiFormsetPrivate->SupportedSchema, Schema= )) { - HiiFormsetLink =3D HiiFormsetNextLink; - continue; - } - - HiiFormLink =3D GetFirstNode (&HiiFormsetPrivate->HiiFormList); - while (!IsNull (&HiiFormsetPrivate->HiiFormList, HiiFormLink)) { - HiiNextFormLink =3D GetNextNode (&HiiFormsetPrivate->HiiFormList, Hi= iFormLink); - HiiFormPrivate =3D REDFISH_PLATFORM_CONFIG_FORM_FROM_LINK (HiiFormLi= nk); - - HiiStatementLink =3DGetFirstNode (&HiiFormPrivate->StatementList); - while (!IsNull (&HiiFormPrivate->StatementList, HiiStatementLink)) { - HiiNextStatementLink =3D GetNextNode (&HiiFormPrivate->StatementLi= st, HiiStatementLink); - HiiStatementPrivate =3D REDFISH_PLATFORM_CONFIG_STATEMENT_FROM_LIN= K (HiiStatementLink); - - if (HiiStatementPrivate->Description !=3D 0) { - TmpString =3D HiiGetRedfishString (HiiFormsetPrivate->HiiHandle,= Schema, HiiStatementPrivate->Description); - if (TmpString !=3D NULL) { - Status =3D RegularExpressionProtocol->MatchString ( - RegularExpressionProtoco= l, - TmpString, - Pattern, - &gEfiRegexSyntaxTypePerl= Guid, - &IsMatch, - NULL, - &CaptureCount - ); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "%a, MatchString \"%s\" failed: %r\n", = __FUNCTION__, Pattern, Status)); - ASSERT (FALSE); - return Status; - } - - // - // Found - // - if (IsMatch) { - StatementRef =3D AllocateZeroPool (sizeof (REDFISH_PLATFORM_= CONFIG_STATEMENT_PRIVATE_REF)); - if (StatementRef =3D=3D NULL) { - return EFI_OUT_OF_RESOURCES; - } - - StatementRef->Statement =3D HiiStatementPrivate; - InsertTailList (&StatementList->StatementList, &StatementRef= ->Link); - ++StatementList->Count; - } - - FreePool (TmpString); - } - } - - HiiStatementLink =3D HiiNextStatementLink; - } - - HiiFormLink =3D HiiNextFormLink; - } - - HiiFormsetLink =3D HiiFormsetNextLink; - } - - return EFI_SUCCESS; -} - -/** - Get statement private instance by the given configure language. - - @param[in] FormsetList Form-set list to search. - @param[in] Schema Schema to be matched. - @param[in] ConfigureLang Configure language. - - @retval REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE * Pointer to stateme= nt private instance. - -**/ -REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE * -GetStatementPrivateByConfigureLang ( - IN LIST_ENTRY *FormsetList, - IN CHAR8 *Schema, - IN EFI_STRING ConfigureLang - ) -{ - LIST_ENTRY *HiiFormsetLink; - LIST_ENTRY *HiiFormsetNextLink; - REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *HiiFormsetPrivate; - LIST_ENTRY *HiiFormLink; - LIST_ENTRY *HiiNextFormLink; - REDFISH_PLATFORM_CONFIG_FORM_PRIVATE *HiiFormPrivate; - LIST_ENTRY *HiiStatementLink; - LIST_ENTRY *HiiNextStatementLink; - REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE *HiiStatementPrivate; - EFI_STRING TmpString; - - if (FormsetList =3D=3D NULL || IS_EMPTY_STRING (Schema) || IS_EMPTY_STRI= NG (ConfigureLang)) { - return NULL; - } - - if (IsListEmpty (FormsetList)) { - return NULL; - } - - HiiFormsetLink =3D GetFirstNode (FormsetList); - while (!IsNull (FormsetList, HiiFormsetLink)) { - HiiFormsetNextLink =3D GetNextNode (FormsetList, HiiFormsetLink); - HiiFormsetPrivate =3D REDFISH_PLATFORM_CONFIG_FORMSET_FROM_LINK (HiiFo= rmsetLink); - - // - // Performance check. - // If there is no desired Redfish schema found, skip this formset. - // - if (!CheckSupportedSchema (&HiiFormsetPrivate->SupportedSchema, Schema= )) { - HiiFormsetLink =3D HiiFormsetNextLink; - continue; - } - - HiiFormLink =3D GetFirstNode (&HiiFormsetPrivate->HiiFormList); - while (!IsNull (&HiiFormsetPrivate->HiiFormList, HiiFormLink)) { - HiiNextFormLink =3D GetNextNode (&HiiFormsetPrivate->HiiFormList, Hi= iFormLink); - HiiFormPrivate =3D REDFISH_PLATFORM_CONFIG_FORM_FROM_LINK (HiiFormLi= nk); - - HiiStatementLink =3DGetFirstNode (&HiiFormPrivate->StatementList); - while (!IsNull (&HiiFormPrivate->StatementList, HiiStatementLink)) { - HiiNextStatementLink =3D GetNextNode (&HiiFormPrivate->StatementLi= st, HiiStatementLink); - HiiStatementPrivate =3D REDFISH_PLATFORM_CONFIG_STATEMENT_FROM_LIN= K (HiiStatementLink); - - DEBUG_CODE ( - STATIC UINTN Index =3D 0; - DEBUG ((DEBUG_INFO, "%a, [%d] search %s in QID: 0x%x form: 0x%x = formset: %g\n", __FUNCTION__, ++Index, ConfigureLang, HiiStatementPrivate->= QuestionId, HiiFormPrivate->Id, &HiiFormsetPrivate->Guid)); - ); - - if (HiiStatementPrivate->Description !=3D 0) { - TmpString =3D HiiGetRedfishString (HiiFormsetPrivate->HiiHandle,= Schema, HiiStatementPrivate->Description); - if (TmpString !=3D NULL) { - if (StrCmp (TmpString, ConfigureLang) =3D=3D 0) { - FreePool (TmpString); - return HiiStatementPrivate; - } - - FreePool (TmpString); - } - } - - HiiStatementLink =3D HiiNextStatementLink; - } - - HiiFormLink =3D HiiNextFormLink; - } - - HiiFormsetLink =3D HiiFormsetNextLink; - } - - return NULL; -} - -/** - Get form-set private instance by the given HII handle. - - @param[in] HiiHandle HII handle instance. - @param[in] FormsetList Form-set list to search. - - @retval REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE * Pointer to form-set= private instance. - -**/ -REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE * -GetFormsetPrivateByHiiHandle ( - IN EFI_HII_HANDLE HiiHandle, - IN LIST_ENTRY *FormsetList - ) -{ - LIST_ENTRY *HiiFormsetLink; - LIST_ENTRY *HiiFormsetNextLink; - REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *HiiFormsetPrivate; - - if (HiiHandle =3D=3D NULL || FormsetList =3D=3D NULL) { - return NULL; - } - - if (IsListEmpty (FormsetList)) { - return NULL; - } - - HiiFormsetLink =3D GetFirstNode (FormsetList); - while (!IsNull (FormsetList, HiiFormsetLink)) { - HiiFormsetNextLink =3D GetNextNode (FormsetList, HiiFormsetLink); - HiiFormsetPrivate =3D REDFISH_PLATFORM_CONFIG_FORMSET_FROM_LINK (HiiFo= rmsetLink); - - if (HiiFormsetPrivate->HiiHandle =3D=3D HiiHandle) { - return HiiFormsetPrivate; - } - - HiiFormsetLink =3D HiiFormsetNextLink; - } - - return NULL; -} - -/** - Release formset and all the forms and statements that belong to this for= mset. - - @param[in] FormsetPrivate Pointer to HP_HII_FORM_SET_PRIVATE - - @retval EFI_STATUS - -**/ -EFI_STATUS -ReleaseFormset ( - IN REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *FormsetPrivate - ) -{ - LIST_ENTRY *HiiFormLink; - LIST_ENTRY *HiiNextFormLink; - REDFISH_PLATFORM_CONFIG_FORM_PRIVATE *HiiFormPrivate; - LIST_ENTRY *HiiStatementLink; - LIST_ENTRY *HiiNextStatementLink; - REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE *HiiStatementPrivate; - UINTN Index; - - if (FormsetPrivate =3D=3D NULL) { - return EFI_INVALID_PARAMETER; - } - - HiiFormLink =3D GetFirstNode (&FormsetPrivate->HiiFormList); - while (!IsNull (&FormsetPrivate->HiiFormList, HiiFormLink)) { - HiiFormPrivate =3D REDFISH_PLATFORM_CONFIG_FORM_FROM_LINK (HiiFormLink= ); - HiiNextFormLink =3D GetNextNode (&FormsetPrivate->HiiFormList, HiiForm= Link); - - HiiStatementLink =3D GetFirstNode (&HiiFormPrivate->StatementList); - while (!IsNull (&HiiFormPrivate->StatementList, HiiStatementLink)) { - HiiStatementPrivate =3D REDFISH_PLATFORM_CONFIG_STATEMENT_FROM_LINK = (HiiStatementLink); - HiiNextStatementLink =3D GetNextNode (&HiiFormPrivate->StatementList= , HiiStatementLink); - - // - // HiiStatementPrivate->HiiStatement will be released in DestroyForm= Set(). - // - - if (HiiStatementPrivate->DesStringCache !=3D NULL) { - FreePool (HiiStatementPrivate->DesStringCache); - HiiStatementPrivate->DesStringCache =3D NULL; - } - - RemoveEntryList (&HiiStatementPrivate->Link); - FreePool (HiiStatementPrivate); - HiiStatementLink =3D HiiNextStatementLink; - } - - // - // HiiStatementPrivate->HiiForm will be released in DestroyFormSet(). - // - - RemoveEntryList (&HiiFormPrivate->Link); - FreePool (HiiFormPrivate); - HiiFormLink =3D HiiNextFormLink; - } - - if (FormsetPrivate->HiiFormSet !=3D NULL) { - DestroyFormSet (FormsetPrivate->HiiFormSet); - FormsetPrivate->HiiFormSet =3D NULL; - } - - FreePool (FormsetPrivate->DevicePathStr); - - // - // Release schema list - // - if (FormsetPrivate->SupportedSchema.SchemaList !=3D NULL) { - for (Index =3D 0; Index < FormsetPrivate->SupportedSchema.Count; Index= ++) { - FreePool (FormsetPrivate->SupportedSchema.SchemaList[Index]); - } - - FreePool (FormsetPrivate->SupportedSchema.SchemaList); - FormsetPrivate->SupportedSchema.SchemaList =3D NULL; - FormsetPrivate->SupportedSchema.Count =3D 0; - } - - return EFI_SUCCESS; -} - -/** - Create new form-set instance. - - @retval REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE * Pointer to newly cr= eated form-set private instance. - -**/ -REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE * -NewFormsetPrivate ( - VOID - ) -{ - REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *NewFormsetPrivate; - - NewFormsetPrivate =3D AllocateZeroPool (sizeof (REDFISH_PLATFORM_CONFIG_= FORM_SET_PRIVATE)); - if (NewFormsetPrivate =3D=3D NULL) { - return NULL; - } - - // - // Initial newly created formset private data. - // - InitializeListHead (&NewFormsetPrivate->HiiFormList); - - return NewFormsetPrivate; -} - -/** - Load the HII formset from the given HII handle. - - @param[in] HiiHandle Target HII handle to load. - @param[out] FormsetPrivate The formset private data. - - @retval EFI_STATUS - -**/ -EFI_STATUS -LoadFormset ( - IN EFI_HII_HANDLE HiiHandle, - OUT REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *FormsetPrivate - ) -{ - EFI_STATUS Status; - HII_FORMSET *HiiFormSet; - HII_FORM *HiiForm; - LIST_ENTRY *HiiFormLink; - REDFISH_PLATFORM_CONFIG_FORM_PRIVATE *HiiFormPrivate; - HII_STATEMENT *HiiStatement; - LIST_ENTRY *HiiStatementLink; - REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE *HiiStatementPrivate; - EFI_GUID ZeroGuid; - - if (HiiHandle =3D=3D NULL || FormsetPrivate =3D=3D NULL) { - return EFI_INVALID_PARAMETER; - } - - - HiiFormSet =3D AllocateZeroPool (sizeof (HII_FORMSET)); - if (HiiFormSet =3D=3D NULL) { - return EFI_OUT_OF_RESOURCES; - } - - // - // Find HII formset by the given HII handle. - // - ZeroMem (&ZeroGuid, sizeof (ZeroGuid)); - Status =3D CreateFormSetFromHiiHandle (HiiHandle, &ZeroGuid, HiiFormSet); - if (EFI_ERROR (Status) || IsListEmpty (&HiiFormSet->FormListHead)) { - Status =3D EFI_NOT_FOUND; - goto ErrorExit; - } - - // - // Initialize formset - // - InitializeFormSet (HiiFormSet); - - // - // Initialize formset private data. - // - FormsetPrivate->HiiFormSet =3D HiiFormSet; - FormsetPrivate->HiiHandle =3D HiiHandle; - CopyGuid (&FormsetPrivate->Guid, &HiiFormSet->Guid); - FormsetPrivate->DevicePathStr =3D ConvertDevicePathToText (HiiFormSet->D= evicePath, FALSE, FALSE); - Status =3D GetSupportedSchema (FormsetPrivate->HiiHandle, &FormsetPrivat= e->SupportedSchema); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_WARN, "%a, No schema from HII handle: 0x%x found: %r\n",= __FUNCTION__, FormsetPrivate->HiiHandle, Status)); - } - - HiiFormLink =3D GetFirstNode (&HiiFormSet->FormListHead); - while (!IsNull (&HiiFormSet->FormListHead, HiiFormLink)) { - HiiForm =3D HII_FORM_FROM_LINK (HiiFormLink); - - HiiFormPrivate =3D AllocateZeroPool (sizeof (REDFISH_PLATFORM_CONFIG_F= ORM_PRIVATE)); - if (HiiFormPrivate =3D=3D NULL) { - Status =3D EFI_OUT_OF_RESOURCES; - goto ErrorExit; - } - - // - // Initialize form private data. - // - HiiFormPrivate->HiiForm =3D HiiForm; - HiiFormPrivate->Id =3D HiiForm->FormId; - HiiFormPrivate->Title =3D HiiForm->FormTitle; - HiiFormPrivate->ParentFormset =3D FormsetPrivate; - InitializeListHead (&HiiFormPrivate->StatementList); - - HiiStatementLink =3D GetFirstNode (&HiiForm->StatementListHead); - while (!IsNull (&HiiForm->StatementListHead, HiiStatementLink)) { - HiiStatement =3D HII_STATEMENT_FROM_LINK (HiiStatementLink); - - HiiStatementPrivate =3D AllocateZeroPool (sizeof (REDFISH_PLATFORM_C= ONFIG_STATEMENT_PRIVATE)); - if (HiiStatementPrivate =3D=3D NULL) { - Status =3D EFI_OUT_OF_RESOURCES; - goto ErrorExit; - } - // - // Initialize statement private data. - // - HiiStatementPrivate->HiiStatement =3D HiiStatement; - HiiStatementPrivate->QuestionId =3D HiiStatement->QuestionId; - HiiStatementPrivate->Description =3D HiiStatement->Prompt; - HiiStatementPrivate->ParentForm =3D HiiFormPrivate; - - // - // Attach to statement list. - // - InsertTailList (&HiiFormPrivate->StatementList, &HiiStatementPrivate= ->Link); - HiiStatementLink =3D GetNextNode (&HiiForm->StatementListHead, HiiSt= atementLink); - } - // - // Attach to form list. - // - InsertTailList (&FormsetPrivate->HiiFormList, &HiiFormPrivate->Link); - HiiFormLink =3D GetNextNode (&HiiFormSet->FormListHead, HiiFormLink); - } - - return EFI_SUCCESS; - -ErrorExit: - - // - // Release HiiFormSet if HiiFormSet is not linked to FormsetPrivate yet. - // - if (HiiFormSet !=3D NULL && FormsetPrivate->HiiFormSet !=3D HiiFormSet) { - DestroyFormSet (HiiFormSet); - } - - // - // Release resource when error happens. - // - ReleaseFormset (FormsetPrivate); - - return Status; -} - -/** - Release formset list and all the forms that belong to this formset. - - @param[in] FormsetList Pointer to formst list that needs to be - released. - - @retval EFI_STATUS - -**/ -EFI_STATUS -LoadFormsetList ( - IN EFI_HII_HANDLE *HiiHandle, - OUT LIST_ENTRY *FormsetList - ) -{ - EFI_STATUS Status; - REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *FormsetPrivate; - - if (HiiHandle =3D=3D NULL || FormsetList =3D=3D NULL) { - return EFI_INVALID_PARAMETER; - } - - FormsetPrivate =3D GetFormsetPrivateByHiiHandle (HiiHandle, FormsetList); - if (FormsetPrivate !=3D NULL) { - return EFI_ALREADY_STARTED; - } - - FormsetPrivate =3D NewFormsetPrivate (); - if (FormsetPrivate =3D=3D NULL) { - DEBUG ((DEBUG_ERROR, "%a, out of resource\n", __FUNCTION__)); - return EFI_OUT_OF_RESOURCES; - } - - // - // Load formset on the given HII handle. - // - Status =3D LoadFormset (HiiHandle, FormsetPrivate); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "%a, failed to load formset: %r\n", __FUNCTION__,= Status)); - FreePool (FormsetPrivate); - return Status; - } - - // - // Attach to cache list. - // - InsertTailList (FormsetList, &FormsetPrivate->Link); - - DEBUG_CODE ( - DumpFormsetList (FormsetList); - ); - - return EFI_SUCCESS; -} - -/** - Release formset list and all the forms that belong to this formset. - - @param[in] FormsetList Pointer to formst list that needs to be - released. - - @retval EFI_STATUS - -**/ -EFI_STATUS -ReleaseFormsetList ( - IN LIST_ENTRY *FormsetList - ) -{ - LIST_ENTRY *HiiFormsetLink; - LIST_ENTRY *HiiFormsetNextLink; - REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *HiiFormsetPrivate; - - if (FormsetList =3D=3D NULL) { - return EFI_INVALID_PARAMETER; - } - - if (IsListEmpty (FormsetList)) { - return EFI_SUCCESS; - } - - HiiFormsetLink =3D GetFirstNode (FormsetList); - while (!IsNull (FormsetList, HiiFormsetLink)) { - HiiFormsetNextLink =3D GetNextNode (FormsetList, HiiFormsetLink); - HiiFormsetPrivate =3D REDFISH_PLATFORM_CONFIG_FORMSET_FROM_LINK (HiiFo= rmsetLink); - - // - // Detach from list. - // - RemoveEntryList (&HiiFormsetPrivate->Link); - ReleaseFormset (HiiFormsetPrivate); - FreePool (HiiFormsetPrivate); - HiiFormsetLink =3D HiiFormsetNextLink; - } - - return EFI_SUCCESS; -} - -/** - Get all pending list. - - @param[in] HiiHandle HII handle instance. - @param[in] PendingList Pending list to keep pending data. - - @retval REDFISH_PLATFORM_CONFIG_PENDING_LIST * Pointer to pending list= data. - -**/ -REDFISH_PLATFORM_CONFIG_PENDING_LIST * -GetPendingList ( - IN EFI_HII_HANDLE *HiiHandle, - IN LIST_ENTRY *PendingList - ) -{ - LIST_ENTRY *PendingListLink; - REDFISH_PLATFORM_CONFIG_PENDING_LIST *Target; - - if (HiiHandle =3D=3D NULL || PendingList =3D=3D NULL) { - return NULL; - } - - if (IsListEmpty (PendingList)) { - return NULL; - } - - PendingListLink =3D GetFirstNode (PendingList); - while (!IsNull (PendingList, PendingListLink)) { - Target =3D REDFISH_PLATFORM_CONFIG_PENDING_LIST_FROM_LINK (PendingList= Link); - - if (Target->HiiHandle =3D=3D HiiHandle) { - return Target; - } - - PendingListLink =3D GetNextNode (PendingList, PendingListLink); - } - - return NULL; -} - -/** - When HII database is updated. Keep updated HII handle into pending list = so - we can process them later. - - @param[in] HiiHandle HII handle instance. - @param[in] PendingList Pending list to keep HII handle which is recentl= y updated. - - @retval EFI_SUCCESS HII handle is saved in pending list. - @retval EFI_INVALID_PARAMETER HiiHnalde is NULL or PendingList is NULL. - @retval EFI_OUT_OF_RESOURCES System is out of memory. - -**/ -EFI_STATUS -NotifyFormsetUpdate ( - IN EFI_HII_HANDLE *HiiHandle, - IN LIST_ENTRY *PendingList - ) -{ - REDFISH_PLATFORM_CONFIG_PENDING_LIST *TargetPendingList; - - if (HiiHandle =3D=3D NULL || PendingList =3D=3D NULL) { - return EFI_INVALID_PARAMETER; - } - - // - // Check and see if this HII handle is processed already. - // - TargetPendingList =3D GetPendingList (HiiHandle, PendingList); - if (TargetPendingList !=3D NULL) { - TargetPendingList->IsDeleted =3D FALSE; - DEBUG_CODE ( - DEBUG ((DEBUG_INFO, "%a, HII handle: 0x%x is updated\n", __FUNCTION__,= HiiHandle)); - ); - return EFI_SUCCESS; - } - - TargetPendingList=3D AllocateZeroPool (sizeof (REDFISH_PLATFORM_CONFIG_P= ENDING_LIST)); - if (TargetPendingList =3D=3D NULL) { - return EFI_OUT_OF_RESOURCES; - } - - TargetPendingList->HiiHandle =3D HiiHandle; - TargetPendingList->IsDeleted =3D FALSE; - - InsertTailList (PendingList, &TargetPendingList->Link); - - DEBUG_CODE ( - DEBUG ((DEBUG_INFO, "%a, HII handle: 0x%x is created\n", __FUNCTION__,= HiiHandle)); - ); - - return EFI_SUCCESS; -} - -/** - When HII database is updated and form-set is deleted. Keep deleted HII h= andle into pending list so - we can process them later. - - @param[in] HiiHandle HII handle instance. - @param[in] PendingList Pending list to keep HII handle which is recentl= y updated. - - @retval EFI_SUCCESS HII handle is saved in pending list. - @retval EFI_INVALID_PARAMETER HiiHnalde is NULL or PendingList is NULL. - @retval EFI_OUT_OF_RESOURCES System is out of memory. - -**/ -EFI_STATUS -NotifyFormsetDeleted ( - IN EFI_HII_HANDLE *HiiHandle, - IN LIST_ENTRY *PendingList - ) -{ - REDFISH_PLATFORM_CONFIG_PENDING_LIST *TargetPendingList; - - if (HiiHandle =3D=3D NULL || PendingList =3D=3D NULL) { - return EFI_INVALID_PARAMETER; - } - - // - // Check and see if this HII handle is processed already. - // - TargetPendingList =3D GetPendingList (HiiHandle, PendingList); - if (TargetPendingList !=3D NULL) { - TargetPendingList->IsDeleted =3D TRUE; - DEBUG_CODE ( - DEBUG ((DEBUG_INFO, "%a, HII handle: 0x%x is updated and deleted\n",= __FUNCTION__, HiiHandle)); - ); - return EFI_SUCCESS; - } - - TargetPendingList=3D AllocateZeroPool (sizeof (REDFISH_PLATFORM_CONFIG_P= ENDING_LIST)); - if (TargetPendingList =3D=3D NULL) { - return EFI_OUT_OF_RESOURCES; - } - - TargetPendingList->HiiHandle =3D HiiHandle; - TargetPendingList->IsDeleted =3D TRUE; - - InsertTailList (PendingList, &TargetPendingList->Link); - - DEBUG_CODE ( - DEBUG ((DEBUG_INFO, "%a, HII handle: 0x%x is deleted\n", __FUNCTION__,= HiiHandle)); - ); - - return EFI_SUCCESS; -} - -/** - There are HII database update and we need to process them accordingly so= that we - won't use stale data. This function will parse updated HII handle again = in order - to get updated data-set. - - @param[in] FormsetList List to keep HII form-set. - @param[in] PendingList List to keep HII handle that is updated. - - @retval EFI_SUCCESS HII handle is saved in pending list. - @retval EFI_INVALID_PARAMETER FormsetList is NULL or PendingList is NU= LL. - -**/ -EFI_STATUS -ProcessPendingList ( - IN LIST_ENTRY *FormsetList, - IN LIST_ENTRY *PendingList - ) -{ - LIST_ENTRY *PendingListLink; - LIST_ENTRY *PendingListNextLink; - REDFISH_PLATFORM_CONFIG_PENDING_LIST *Target; - REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *FormsetPrivate; - EFI_STATUS Status; - - - if (FormsetList =3D=3D NULL || PendingList =3D=3D NULL) { - return EFI_INVALID_PARAMETER; - } - - if (IsListEmpty (PendingList)) { - return EFI_SUCCESS; - } - - PendingListLink =3D GetFirstNode (PendingList); - while (!IsNull (PendingList, PendingListLink)) { - PendingListNextLink =3D GetNextNode (PendingList, PendingListLink); - Target =3D REDFISH_PLATFORM_CONFIG_PENDING_LIST_FROM_LINK (PendingList= Link); - - if (Target->IsDeleted) { - // - // The HII resource on this HII handle is removed. Release the forms= et. - // - FormsetPrivate =3D GetFormsetPrivateByHiiHandle (Target->HiiHandle, = FormsetList); - if (FormsetPrivate !=3D NULL) { - DEBUG ((DEBUG_INFO, "%a, formset: %g is removed because driver rel= ease HII resource it already\n", __FUNCTION__, FormsetPrivate->Guid)); - RemoveEntryList (&FormsetPrivate->Link); - ReleaseFormset (FormsetPrivate); - FreePool (FormsetPrivate); - } else { - DEBUG ((DEBUG_WARN, "%a, formset on HII handle 0x%x was removed al= ready\n", __FUNCTION__, Target->HiiHandle)); - } - } else { - // - // The HII resource on this HII handle is updated/removed. - // - FormsetPrivate =3D GetFormsetPrivateByHiiHandle (Target->HiiHandle, = FormsetList); - if (FormsetPrivate !=3D NULL) { - // - // HII formset already exist, release it and query again. - // - DEBUG ((DEBUG_INFO, "%a, formset: %g is updated. Release current f= ormset\n", __FUNCTION__, &FormsetPrivate->Guid)); - RemoveEntryList (&FormsetPrivate->Link); - ReleaseFormset (FormsetPrivate); - FreePool (FormsetPrivate); - } - - Status =3D LoadFormsetList (Target->HiiHandle, FormsetList); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "%a, load formset from HII handle: 0x%x faile= d: %r\n", __FUNCTION__, Target->HiiHandle, Status)); - } - } - - // - // Detach it from list first. - // - RemoveEntryList (&Target->Link); - FreePool (Target); - - PendingListLink =3D PendingListNextLink; - } - - return EFI_SUCCESS; -} - -/** - Release all resource in statement list. - - @param[in] StatementList Statement list to be released. - - @retval EFI_SUCCESS All resource are released. - @retval EFI_INVALID_PARAMETER StatementList is NULL. - -**/ -EFI_STATUS -ReleaseStatementList ( - IN REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_LIST *StatementList - ) -{ - REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_REF *StatementRef; - LIST_ENTRY *NextLink; - - if (StatementList =3D=3D NULL) { - return EFI_INVALID_PARAMETER; - } - - if (IsListEmpty (&StatementList->StatementList)) { - return EFI_SUCCESS; - } - - NextLink =3D GetFirstNode (&StatementList->StatementList); - while (!IsNull (&StatementList->StatementList, NextLink)) { - StatementRef =3D REDFISH_PLATFORM_CONFIG_STATEMENT_REF_FROM_LINK (Next= Link); - NextLink =3D GetNextNode (&StatementList->StatementList, NextLink); - - RemoveEntryList (&StatementRef->Link); - FreePool (StatementRef); - } - - return EFI_SUCCESS; -} +/** @file + + The implementation of EDKII Redfidh Platform Config Protocol. + + (C) Copyright 2021-2022 Hewlett Packard Enterprise Development LP
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ +#include "RedfishPlatformConfigDxe.h" +#include "RedfishPlatformConfigImpl.h" + +extern REDFISH_PLATFORM_CONFIG_PRIVATE *mRedfishPlatformConfigPrivate; + +/** + Debug dump HII string + + @param[in] HiiHandle HII handle instance + @param[in] StringId HII string to dump + + @retval EFI_SUCCESS Dump HII string successfully + @retval Others Errors occur + +**/ +EFI_STATUS +DumpHiiString ( + IN EFI_HII_HANDLE HiiHandle, + IN EFI_STRING_ID StringId + ) +{ + EFI_STRING String; + + if (HiiHandle =3D=3D NULL || StringId =3D=3D 0) { + DEBUG ((DEBUG_INFO, "???")); + return EFI_INVALID_PARAMETER; + } + + String =3D HiiGetString (HiiHandle, StringId, NULL); + if (String =3D=3D NULL) { + return EFI_NOT_FOUND; + } + + DEBUG ((DEBUG_INFO, "%s", String)); + FreePool (String); + + return EFI_SUCCESS; +} + +/** + Debug dump HII form-set data + + @param[in] FormsetPrivate HII form-set private instance. + + @retval EFI_SUCCESS Dump form-set successfully + @retval Others Errors occur + +**/ +EFI_STATUS +DumpFormset ( + IN REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *FormsetPrivate + ) +{ + LIST_ENTRY *HiiFormLink; + LIST_ENTRY *HiiNextFormLink; + REDFISH_PLATFORM_CONFIG_FORM_PRIVATE *HiiFormPrivate; + LIST_ENTRY *HiiStatementLink; + LIST_ENTRY *HiiNextStatementLink; + REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE *HiiStatementPrivate; + UINTN Index; + + if (FormsetPrivate =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + + Index =3D 0; + HiiFormLink =3D GetFirstNode (&FormsetPrivate->HiiFormList); + while (!IsNull (&FormsetPrivate->HiiFormList, HiiFormLink)) { + HiiFormPrivate =3D REDFISH_PLATFORM_CONFIG_FORM_FROM_LINK (HiiFormLink= ); + HiiNextFormLink =3D GetNextNode (&FormsetPrivate->HiiFormList, HiiForm= Link); + + DEBUG ((DEBUG_INFO, " [%d] form: %d title: ", ++Index, HiiFormPrivate= ->Id)); + DumpHiiString (FormsetPrivate->HiiHandle, HiiFormPrivate->Title); + DEBUG ((DEBUG_INFO, "\n")); + + HiiStatementLink =3D GetFirstNode (&HiiFormPrivate->StatementList); + while (!IsNull (&HiiFormPrivate->StatementList, HiiStatementLink)) { + HiiStatementPrivate =3D REDFISH_PLATFORM_CONFIG_STATEMENT_FROM_LINK = (HiiStatementLink); + HiiNextStatementLink =3D GetNextNode (&HiiFormPrivate->StatementList= , HiiStatementLink); + + DEBUG ((DEBUG_INFO, " QID: 0x%x Prompt: ", HiiStatementPrivate->Q= uestionId)); + DumpHiiString (FormsetPrivate->HiiHandle, HiiStatementPrivate->Descr= iption); + DEBUG ((DEBUG_INFO, "\n")); + + HiiStatementLink =3D HiiNextStatementLink; + } + + HiiFormLink =3D HiiNextFormLink; + } + + return EFI_SUCCESS; +} + +/** + Debug dump HII form-set list + + @param[in] FormsetList Form-set list instance + + @retval EFI_SUCCESS Dump list successfully + @retval Others Errors occur + +**/ +EFI_STATUS +DumpFormsetList ( + IN LIST_ENTRY *FormsetList + ) +{ + LIST_ENTRY *HiiFormsetLink; + LIST_ENTRY *HiiFormsetNextLink; + REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *HiiFormsetPrivate; + UINTN Index; + + if (FormsetList =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + + if (IsListEmpty (FormsetList)) { + DEBUG ((DEBUG_INFO, "%a, Empty formset list\n", __FUNCTION__)); + return EFI_SUCCESS; + } + + Index =3D 0; + HiiFormsetLink =3D GetFirstNode (FormsetList); + while (!IsNull (FormsetList, HiiFormsetLink)) { + HiiFormsetNextLink =3D GetNextNode (FormsetList, HiiFormsetLink); + HiiFormsetPrivate =3D REDFISH_PLATFORM_CONFIG_FORMSET_FROM_LINK (HiiFo= rmsetLink); + + DEBUG ((DEBUG_INFO, "[%d] HII Handle: 0x%x formset: %g at %s\n", ++Ind= ex, HiiFormsetPrivate->HiiHandle, &HiiFormsetPrivate->Guid, HiiFormsetPriva= te->DevicePathStr)); + DumpFormset (HiiFormsetPrivate); + + HiiFormsetLink =3D HiiFormsetNextLink; + } + + return EFI_SUCCESS; +} + +/** + Retrieves a unicode string from a string package in a given language. The + returned string is allocated using AllocatePool(). The caller is respon= sible + for freeing the allocated buffer using FreePool(). + + If HiiHandle is NULL, then ASSERT(). + If StringId is 0, then ASSET. + + @param[in] HiiHandle A handle that was previously registered in= the HII Database. + @param[in] Language The specified configure language to get st= ring. + @param[in] StringId The identifier of the string to retrieved = from the string + package associated with HiiHandle. + + @retval NULL The string specified by StringId is not present in the st= ring package. + @retval Other The string was returned. + +**/ +EFI_STRING +HiiGetRedfishString ( + IN EFI_HII_HANDLE HiiHandle, + IN CHAR8 *Language, + IN EFI_STRING_ID StringId + ) +{ + EFI_STATUS Status; + UINTN StringSize; + CHAR16 TempString; + EFI_STRING String; + + if (mRedfishPlatformConfigPrivate->HiiString =3D=3D NULL || HiiHandle = =3D=3D NULL || StringId =3D=3D 0 || IS_EMPTY_STRING (Language)) { + ASSERT (FALSE); + return NULL; + } + + // + // Retrieve the size of the string in the string package for the BestLan= guage + // + StringSize =3D 0; + Status =3D mRedfishPlatformConfigPrivate->HiiString->GetString ( + mRedfishPlatformConfigPrivate= ->HiiString, + Language, + HiiHandle, + StringId, + &TempString, + &StringSize, + NULL + ); + // + // If GetString() returns EFI_SUCCESS for a zero size, + // then there are no supported languages registered for HiiHandle. If G= etString() + // returns an error other than EFI_BUFFER_TOO_SMALL, then HiiHandle is n= ot present + // in the HII Database + // + if (Status !=3D EFI_BUFFER_TOO_SMALL) { + return NULL; + } + + // + // Allocate a buffer for the return string + // + String =3D AllocateZeroPool (StringSize); + if (String =3D=3D NULL) { + return NULL; + } + + // + // Retrieve the string from the string package + // + Status =3D mRedfishPlatformConfigPrivate->HiiString->GetString ( + mRedfishPlatformConfigPrivate= ->HiiString, + Language, + HiiHandle, + StringId, + String, + &StringSize, + NULL + ); + if (EFI_ERROR (Status)) { + // + // Free the buffer and return NULL if the supported languages can not = be retrieved. + // + FreePool (String); + String =3D NULL; + } + + // + // Return the Null-terminated Unicode string + // + return String; +} + +/** + Retrieves a ASCII string from a string package in a given language. The + returned string is allocated using AllocatePool(). The caller is respon= sible + for freeing the allocated buffer using FreePool(). + + If HiiHandle is NULL, then ASSERT(). + If StringId is 0, then ASSET. + + @param[in] HiiHandle A handle that was previously registered in= the HII Database. + @param[in] Language The specified configure language to get st= ring. + @param[in] StringId The identifier of the string to retrieved = from the string + package associated with HiiHandle. + + @retval NULL The string specified by StringId is not present in the st= ring package. + @retval Other The string was returned. + +**/ +CHAR8 * +HiiGetRedfishAsciiString ( + IN EFI_HII_HANDLE HiiHandle, + IN CHAR8 *Language, + IN EFI_STRING_ID StringId + ) +{ + EFI_STRING HiiString; + UINTN StringSize; + CHAR8 *AsciiString; + + HiiString =3D HiiGetRedfishString (HiiHandle, Language, StringId); + if (HiiString =3D=3D NULL) { + DEBUG ((DEBUG_ERROR, "%a, Can not find string ID: 0x%x with %a\n", __F= UNCTION__, StringId, Language)); + return NULL; + } + + StringSize =3D (StrLen (HiiString) + 1) * sizeof (CHAR8); + AsciiString =3D AllocatePool (StringSize); + if (AsciiString =3D=3D NULL) { + return NULL; + } + + UnicodeStrToAsciiStrS (HiiString, AsciiString, StringSize); + + FreePool (HiiString); + return AsciiString; +} + +/** + Get string from HII database in English language. + + @param[in] HiiHandle A handle that was previously registered in= the HII Database. + @param[in] StringId The identifier of the string to retrieved = from the string + package associated with HiiHandle. + + @retval NULL The string specified by StringId is not present in the st= ring package. + @retval Other The string was returned. + +**/ +EFI_STRING +HiiGetEnglishString ( + IN EFI_HII_HANDLE HiiHandle, + IN EFI_STRING_ID StringId + ) +{ + return HiiGetRedfishString (HiiHandle, ENGLISH_LANGUAGE_CODE, StringId); +} + +/** + Check and see if this is supported schema or not. + + @param[in] SupportedSchema The list of supported schema. + @param[in] Schema Schema string to be checked. + + @retval BOOLEAN TRUE if this is supported schema. FALSE ot= herwise. + +**/ +BOOLEAN +CheckSupportedSchema ( + IN REDFISH_PLATFORM_CONFIG_SCHEMA *SupportedSchema, + IN CHAR8 *Schema + ) +{ + UINTN Index; + + if (SupportedSchema =3D=3D NULL || IS_EMPTY_STRING (Schema)) { + return FALSE; + } + + if (SupportedSchema->Count =3D=3D 0) { + return FALSE; + } + + for (Index =3D 0; Index < SupportedSchema->Count; Index++) { + if (AsciiStrCmp (SupportedSchema->SchemaList[Index], Schema) =3D=3D 0)= { + return TRUE; + } + } + + return FALSE; +} + +/** + Get the list of supported schema from the given HII handle. + + @param[in] HiiHandle HII handle instance. + @param[out] SupportedSchema Supported schema on this HII handle. + + @retval EFI_SUCCESS Schema list is returned. + @retval EFI_INVALID_PARAMETER HiiHandle is NULL or SupportedSchema is NU= LL. + @retval EFI_NOT_FOUND No supported schema found. + @retval EFI_OUT_OF_RESOURCES System is out of memory. + +**/ +EFI_STATUS +GetSupportedSchema ( + IN EFI_HII_HANDLE HiiHandle, + OUT REDFISH_PLATFORM_CONFIG_SCHEMA *SupportedSchema + ) +{ + CHAR8 *SupportedLanguages; + UINTN Index; + UINTN LangIndex; + UINTN Count; + UINTN StrSize; + UINTN ListIndex; + + if (HiiHandle =3D=3D NULL || SupportedSchema =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + + SupportedSchema->Count =3D 0; + + SupportedLanguages =3D HiiGetSupportedLanguages (HiiHandle); + if (SupportedLanguages =3D=3D NULL) { + return EFI_NOT_FOUND; + } + + Index =3D 0; + LangIndex =3D 0; + Count =3D 0; + while (TRUE) { + if (SupportedLanguages[Index] =3D=3D ';' || SupportedLanguages[Index] = =3D=3D '\0') { + if (AsciiStrnCmp (&SupportedLanguages[LangIndex], X_UEFI_SCHEMA_PREF= IX, AsciiStrLen (X_UEFI_SCHEMA_PREFIX)) =3D=3D 0) { + ++Count; + } + LangIndex =3D Index + 1; + } + + if (SupportedLanguages[Index] =3D=3D '\0') { + break; + } + + ++Index; + } + + if (Count =3D=3D 0) { + return EFI_NOT_FOUND; + } + + SupportedSchema->Count =3D Count; + SupportedSchema->SchemaList =3D AllocatePool (sizeof (CHAR8 *) * Count); + if (SupportedSchema->SchemaList =3D=3D NULL) { + return EFI_OUT_OF_RESOURCES; + } + + Index =3D 0; + LangIndex =3D 0; + ListIndex =3D 0; + while (TRUE) { + + if (SupportedLanguages[Index] =3D=3D ';' || SupportedLanguages[Index] = =3D=3D '\0') { + if (AsciiStrnCmp (&SupportedLanguages[LangIndex], X_UEFI_SCHEMA_PREF= IX, AsciiStrLen (X_UEFI_SCHEMA_PREFIX)) =3D=3D 0) { + StrSize =3D Index - LangIndex; + SupportedSchema->SchemaList[ListIndex] =3D AllocateCopyPool ((StrS= ize + 1), &SupportedLanguages[LangIndex]); + SupportedSchema->SchemaList[ListIndex][StrSize] =3D '\0'; + ++ListIndex; + } + + LangIndex =3D Index + 1; + } + + if (SupportedLanguages[Index] =3D=3D '\0') { + break; + } + + ++Index; + } + + return EFI_SUCCESS; +} + +/** + Search and find statement private instance by given regular expression p= atthern + which describes the Configure Language. + + @param[in] RegularExpressionProtocol Regular express protocol. + @param[in] FormsetList Form-set list to search. + @param[in] Schema Schema to be matched. + @param[in] Pattern Regular expression pattern. + @param[out] StatementList Statement list that match above = pattern. + + @retval EFI_SUCCESS Statement list is returned. + @retval EFI_INVALID_PARAMETER Input parameter is NULL. + @retval EFI_NOT_READY Regular express protocol is NULL. + @retval EFI_NOT_FOUND No statement is found. + @retval EFI_OUT_OF_RESOURCES System is out of memory. + +**/ +EFI_STATUS +GetStatementPrivateByConfigureLangRegex ( + IN EFI_REGULAR_EXPRESSION_PROTOCOL *RegularExpressionPr= otocol, + IN LIST_ENTRY *FormsetList, + IN CHAR8 *Schema, + IN EFI_STRING Pattern, + OUT REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_LIST *StatementList + ) +{ + LIST_ENTRY *HiiFormsetLink; + LIST_ENTRY *HiiFormsetNextLink; + REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *HiiFormsetPrivate; + LIST_ENTRY *HiiFormLink; + LIST_ENTRY *HiiNextFormLink; + REDFISH_PLATFORM_CONFIG_FORM_PRIVATE *HiiFormPrivate; + LIST_ENTRY *HiiStatementLink; + LIST_ENTRY *HiiNextStatementLink; + REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE *HiiStatementPrivate; + EFI_STRING TmpString; + UINTN CaptureCount; + BOOLEAN IsMatch; + EFI_STATUS Status; + REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_REF *StatementRef; + + if (FormsetList =3D=3D NULL || IS_EMPTY_STRING (Schema) || IS_EMPTY_STRI= NG (Pattern) || StatementList =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + + if (RegularExpressionProtocol =3D=3D NULL) { + return EFI_NOT_READY; + } + + StatementList->Count =3D 0; + InitializeListHead (&StatementList->StatementList); + + if (IsListEmpty (FormsetList)) { + return EFI_NOT_FOUND; + } + + HiiFormsetLink =3D GetFirstNode (FormsetList); + while (!IsNull (FormsetList, HiiFormsetLink)) { + HiiFormsetNextLink =3D GetNextNode (FormsetList, HiiFormsetLink); + HiiFormsetPrivate =3D REDFISH_PLATFORM_CONFIG_FORMSET_FROM_LINK (HiiFo= rmsetLink); + + // + // Performance check. + // If there is no desired Redfish schema found, skip this formset. + // + if (!CheckSupportedSchema (&HiiFormsetPrivate->SupportedSchema, Schema= )) { + HiiFormsetLink =3D HiiFormsetNextLink; + continue; + } + + HiiFormLink =3D GetFirstNode (&HiiFormsetPrivate->HiiFormList); + while (!IsNull (&HiiFormsetPrivate->HiiFormList, HiiFormLink)) { + HiiNextFormLink =3D GetNextNode (&HiiFormsetPrivate->HiiFormList, Hi= iFormLink); + HiiFormPrivate =3D REDFISH_PLATFORM_CONFIG_FORM_FROM_LINK (HiiFormLi= nk); + + HiiStatementLink =3DGetFirstNode (&HiiFormPrivate->StatementList); + while (!IsNull (&HiiFormPrivate->StatementList, HiiStatementLink)) { + HiiNextStatementLink =3D GetNextNode (&HiiFormPrivate->StatementLi= st, HiiStatementLink); + HiiStatementPrivate =3D REDFISH_PLATFORM_CONFIG_STATEMENT_FROM_LIN= K (HiiStatementLink); + + if (HiiStatementPrivate->Description !=3D 0) { + TmpString =3D HiiGetRedfishString (HiiFormsetPrivate->HiiHandle,= Schema, HiiStatementPrivate->Description); + if (TmpString !=3D NULL) { + Status =3D RegularExpressionProtocol->MatchString ( + RegularExpressionProtoco= l, + TmpString, + Pattern, + &gEfiRegexSyntaxTypePerl= Guid, + &IsMatch, + NULL, + &CaptureCount + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a, MatchString \"%s\" failed: %r\n", = __FUNCTION__, Pattern, Status)); + ASSERT (FALSE); + return Status; + } + + // + // Found + // + if (IsMatch) { + StatementRef =3D AllocateZeroPool (sizeof (REDFISH_PLATFORM_= CONFIG_STATEMENT_PRIVATE_REF)); + if (StatementRef =3D=3D NULL) { + return EFI_OUT_OF_RESOURCES; + } + + StatementRef->Statement =3D HiiStatementPrivate; + InsertTailList (&StatementList->StatementList, &StatementRef= ->Link); + ++StatementList->Count; + } + + FreePool (TmpString); + } + } + + HiiStatementLink =3D HiiNextStatementLink; + } + + HiiFormLink =3D HiiNextFormLink; + } + + HiiFormsetLink =3D HiiFormsetNextLink; + } + + return EFI_SUCCESS; +} + +/** + Get statement private instance by the given configure language. + + @param[in] FormsetList Form-set list to search. + @param[in] Schema Schema to be matched. + @param[in] ConfigureLang Configure language. + + @retval REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE * Pointer to stateme= nt private instance. + +**/ +REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE * +GetStatementPrivateByConfigureLang ( + IN LIST_ENTRY *FormsetList, + IN CHAR8 *Schema, + IN EFI_STRING ConfigureLang + ) +{ + LIST_ENTRY *HiiFormsetLink; + LIST_ENTRY *HiiFormsetNextLink; + REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *HiiFormsetPrivate; + LIST_ENTRY *HiiFormLink; + LIST_ENTRY *HiiNextFormLink; + REDFISH_PLATFORM_CONFIG_FORM_PRIVATE *HiiFormPrivate; + LIST_ENTRY *HiiStatementLink; + LIST_ENTRY *HiiNextStatementLink; + REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE *HiiStatementPrivate; + EFI_STRING TmpString; + + if (FormsetList =3D=3D NULL || IS_EMPTY_STRING (Schema) || IS_EMPTY_STRI= NG (ConfigureLang)) { + return NULL; + } + + if (IsListEmpty (FormsetList)) { + return NULL; + } + + HiiFormsetLink =3D GetFirstNode (FormsetList); + while (!IsNull (FormsetList, HiiFormsetLink)) { + HiiFormsetNextLink =3D GetNextNode (FormsetList, HiiFormsetLink); + HiiFormsetPrivate =3D REDFISH_PLATFORM_CONFIG_FORMSET_FROM_LINK (HiiFo= rmsetLink); + + // + // Performance check. + // If there is no desired Redfish schema found, skip this formset. + // + if (!CheckSupportedSchema (&HiiFormsetPrivate->SupportedSchema, Schema= )) { + HiiFormsetLink =3D HiiFormsetNextLink; + continue; + } + + HiiFormLink =3D GetFirstNode (&HiiFormsetPrivate->HiiFormList); + while (!IsNull (&HiiFormsetPrivate->HiiFormList, HiiFormLink)) { + HiiNextFormLink =3D GetNextNode (&HiiFormsetPrivate->HiiFormList, Hi= iFormLink); + HiiFormPrivate =3D REDFISH_PLATFORM_CONFIG_FORM_FROM_LINK (HiiFormLi= nk); + + HiiStatementLink =3DGetFirstNode (&HiiFormPrivate->StatementList); + while (!IsNull (&HiiFormPrivate->StatementList, HiiStatementLink)) { + HiiNextStatementLink =3D GetNextNode (&HiiFormPrivate->StatementLi= st, HiiStatementLink); + HiiStatementPrivate =3D REDFISH_PLATFORM_CONFIG_STATEMENT_FROM_LIN= K (HiiStatementLink); + + DEBUG_CODE ( + STATIC UINTN Index =3D 0; + DEBUG ((DEBUG_INFO, "%a, [%d] search %s in QID: 0x%x form: 0x%x = formset: %g\n", __FUNCTION__, ++Index, ConfigureLang, HiiStatementPrivate->= QuestionId, HiiFormPrivate->Id, &HiiFormsetPrivate->Guid)); + ); + + if (HiiStatementPrivate->Description !=3D 0) { + TmpString =3D HiiGetRedfishString (HiiFormsetPrivate->HiiHandle,= Schema, HiiStatementPrivate->Description); + if (TmpString !=3D NULL) { + if (StrCmp (TmpString, ConfigureLang) =3D=3D 0) { + FreePool (TmpString); + return HiiStatementPrivate; + } + + FreePool (TmpString); + } + } + + HiiStatementLink =3D HiiNextStatementLink; + } + + HiiFormLink =3D HiiNextFormLink; + } + + HiiFormsetLink =3D HiiFormsetNextLink; + } + + return NULL; +} + +/** + Get form-set private instance by the given HII handle. + + @param[in] HiiHandle HII handle instance. + @param[in] FormsetList Form-set list to search. + + @retval REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE * Pointer to form-set= private instance. + +**/ +REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE * +GetFormsetPrivateByHiiHandle ( + IN EFI_HII_HANDLE HiiHandle, + IN LIST_ENTRY *FormsetList + ) +{ + LIST_ENTRY *HiiFormsetLink; + LIST_ENTRY *HiiFormsetNextLink; + REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *HiiFormsetPrivate; + + if (HiiHandle =3D=3D NULL || FormsetList =3D=3D NULL) { + return NULL; + } + + if (IsListEmpty (FormsetList)) { + return NULL; + } + + HiiFormsetLink =3D GetFirstNode (FormsetList); + while (!IsNull (FormsetList, HiiFormsetLink)) { + HiiFormsetNextLink =3D GetNextNode (FormsetList, HiiFormsetLink); + HiiFormsetPrivate =3D REDFISH_PLATFORM_CONFIG_FORMSET_FROM_LINK (HiiFo= rmsetLink); + + if (HiiFormsetPrivate->HiiHandle =3D=3D HiiHandle) { + return HiiFormsetPrivate; + } + + HiiFormsetLink =3D HiiFormsetNextLink; + } + + return NULL; +} + +/** + Release formset and all the forms and statements that belong to this for= mset. + + @param[in] FormsetPrivate Pointer to HP_HII_FORM_SET_PRIVATE + + @retval EFI_STATUS + +**/ +EFI_STATUS +ReleaseFormset ( + IN REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *FormsetPrivate + ) +{ + LIST_ENTRY *HiiFormLink; + LIST_ENTRY *HiiNextFormLink; + REDFISH_PLATFORM_CONFIG_FORM_PRIVATE *HiiFormPrivate; + LIST_ENTRY *HiiStatementLink; + LIST_ENTRY *HiiNextStatementLink; + REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE *HiiStatementPrivate; + UINTN Index; + + if (FormsetPrivate =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + + HiiFormLink =3D GetFirstNode (&FormsetPrivate->HiiFormList); + while (!IsNull (&FormsetPrivate->HiiFormList, HiiFormLink)) { + HiiFormPrivate =3D REDFISH_PLATFORM_CONFIG_FORM_FROM_LINK (HiiFormLink= ); + HiiNextFormLink =3D GetNextNode (&FormsetPrivate->HiiFormList, HiiForm= Link); + + HiiStatementLink =3D GetFirstNode (&HiiFormPrivate->StatementList); + while (!IsNull (&HiiFormPrivate->StatementList, HiiStatementLink)) { + HiiStatementPrivate =3D REDFISH_PLATFORM_CONFIG_STATEMENT_FROM_LINK = (HiiStatementLink); + HiiNextStatementLink =3D GetNextNode (&HiiFormPrivate->StatementList= , HiiStatementLink); + + // + // HiiStatementPrivate->HiiStatement will be released in DestroyForm= Set(). + // + + if (HiiStatementPrivate->DesStringCache !=3D NULL) { + FreePool (HiiStatementPrivate->DesStringCache); + HiiStatementPrivate->DesStringCache =3D NULL; + } + + RemoveEntryList (&HiiStatementPrivate->Link); + FreePool (HiiStatementPrivate); + HiiStatementLink =3D HiiNextStatementLink; + } + + // + // HiiStatementPrivate->HiiForm will be released in DestroyFormSet(). + // + + RemoveEntryList (&HiiFormPrivate->Link); + FreePool (HiiFormPrivate); + HiiFormLink =3D HiiNextFormLink; + } + + if (FormsetPrivate->HiiFormSet !=3D NULL) { + DestroyFormSet (FormsetPrivate->HiiFormSet); + FormsetPrivate->HiiFormSet =3D NULL; + } + + if (FormsetPrivate->DevicePathStr !=3D NULL) { + FreePool(FormsetPrivate->DevicePathStr); + } + + // + // Release schema list + // + if (FormsetPrivate->SupportedSchema.SchemaList !=3D NULL) { + for (Index =3D 0; Index < FormsetPrivate->SupportedSchema.Count; Index= ++) { + FreePool (FormsetPrivate->SupportedSchema.SchemaList[Index]); + } + + FreePool (FormsetPrivate->SupportedSchema.SchemaList); + FormsetPrivate->SupportedSchema.SchemaList =3D NULL; + FormsetPrivate->SupportedSchema.Count =3D 0; + } + + return EFI_SUCCESS; +} + +/** + Create new form-set instance. + + @retval REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE * Pointer to newly cr= eated form-set private instance. + +**/ +REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE * +NewFormsetPrivate ( + VOID + ) +{ + REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *NewFormsetPrivate; + + NewFormsetPrivate =3D AllocateZeroPool (sizeof (REDFISH_PLATFORM_CONFIG_= FORM_SET_PRIVATE)); + if (NewFormsetPrivate =3D=3D NULL) { + return NULL; + } + + // + // Initial newly created formset private data. + // + InitializeListHead (&NewFormsetPrivate->HiiFormList); + + return NewFormsetPrivate; +} + +/** + Load the HII formset from the given HII handle. + + @param[in] HiiHandle Target HII handle to load. + @param[out] FormsetPrivate The formset private data. + + @retval EFI_STATUS + +**/ +EFI_STATUS +LoadFormset ( + IN EFI_HII_HANDLE HiiHandle, + OUT REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *FormsetPrivate + ) +{ + EFI_STATUS Status; + HII_FORMSET *HiiFormSet; + HII_FORM *HiiForm; + LIST_ENTRY *HiiFormLink; + REDFISH_PLATFORM_CONFIG_FORM_PRIVATE *HiiFormPrivate; + HII_STATEMENT *HiiStatement; + LIST_ENTRY *HiiStatementLink; + REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE *HiiStatementPrivate; + EFI_GUID ZeroGuid; + + if (HiiHandle =3D=3D NULL || FormsetPrivate =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + + + HiiFormSet =3D AllocateZeroPool (sizeof (HII_FORMSET)); + if (HiiFormSet =3D=3D NULL) { + return EFI_OUT_OF_RESOURCES; + } + + // + // Find HII formset by the given HII handle. + // + ZeroMem (&ZeroGuid, sizeof (ZeroGuid)); + Status =3D CreateFormSetFromHiiHandle (HiiHandle, &ZeroGuid, HiiFormSet); + if (EFI_ERROR (Status) || IsListEmpty (&HiiFormSet->FormListHead)) { + Status =3D EFI_NOT_FOUND; + goto ErrorExit; + } + + // + // Initialize formset + // + InitializeFormSet (HiiFormSet); + + // + // Initialize formset private data. + // + FormsetPrivate->HiiFormSet =3D HiiFormSet; + FormsetPrivate->HiiHandle =3D HiiHandle; + CopyGuid (&FormsetPrivate->Guid, &HiiFormSet->Guid); + FormsetPrivate->DevicePathStr =3D ConvertDevicePathToText (HiiFormSet->D= evicePath, FALSE, FALSE); + Status =3D GetSupportedSchema (FormsetPrivate->HiiHandle, &FormsetPrivat= e->SupportedSchema); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_WARN, "%a, No schema from HII handle: 0x%x found: %r\n",= __FUNCTION__, FormsetPrivate->HiiHandle, Status)); + } + + HiiFormLink =3D GetFirstNode (&HiiFormSet->FormListHead); + while (!IsNull (&HiiFormSet->FormListHead, HiiFormLink)) { + HiiForm =3D HII_FORM_FROM_LINK (HiiFormLink); + + HiiFormPrivate =3D AllocateZeroPool (sizeof (REDFISH_PLATFORM_CONFIG_F= ORM_PRIVATE)); + if (HiiFormPrivate =3D=3D NULL) { + Status =3D EFI_OUT_OF_RESOURCES; + goto ErrorExit; + } + + // + // Initialize form private data. + // + HiiFormPrivate->HiiForm =3D HiiForm; + HiiFormPrivate->Id =3D HiiForm->FormId; + HiiFormPrivate->Title =3D HiiForm->FormTitle; + HiiFormPrivate->ParentFormset =3D FormsetPrivate; + InitializeListHead (&HiiFormPrivate->StatementList); + + HiiStatementLink =3D GetFirstNode (&HiiForm->StatementListHead); + while (!IsNull (&HiiForm->StatementListHead, HiiStatementLink)) { + HiiStatement =3D HII_STATEMENT_FROM_LINK (HiiStatementLink); + + HiiStatementPrivate =3D AllocateZeroPool (sizeof (REDFISH_PLATFORM_C= ONFIG_STATEMENT_PRIVATE)); + if (HiiStatementPrivate =3D=3D NULL) { + Status =3D EFI_OUT_OF_RESOURCES; + goto ErrorExit; + } + // + // Initialize statement private data. + // + HiiStatementPrivate->HiiStatement =3D HiiStatement; + HiiStatementPrivate->QuestionId =3D HiiStatement->QuestionId; + HiiStatementPrivate->Description =3D HiiStatement->Prompt; + HiiStatementPrivate->ParentForm =3D HiiFormPrivate; + + // + // Attach to statement list. + // + InsertTailList (&HiiFormPrivate->StatementList, &HiiStatementPrivate= ->Link); + HiiStatementLink =3D GetNextNode (&HiiForm->StatementListHead, HiiSt= atementLink); + } + // + // Attach to form list. + // + InsertTailList (&FormsetPrivate->HiiFormList, &HiiFormPrivate->Link); + HiiFormLink =3D GetNextNode (&HiiFormSet->FormListHead, HiiFormLink); + } + + return EFI_SUCCESS; + +ErrorExit: + + // + // Release HiiFormSet if HiiFormSet is not linked to FormsetPrivate yet. + // + if (HiiFormSet !=3D NULL && FormsetPrivate->HiiFormSet !=3D HiiFormSet) { + DestroyFormSet (HiiFormSet); + } + + // + // Release resource when error happens. + // + ReleaseFormset (FormsetPrivate); + + return Status; +} + +/** + Release formset list and all the forms that belong to this formset. + + @param[in] FormsetList Pointer to formst list that needs to be + released. + + @retval EFI_STATUS + +**/ +EFI_STATUS +LoadFormsetList ( + IN EFI_HII_HANDLE *HiiHandle, + OUT LIST_ENTRY *FormsetList + ) +{ + EFI_STATUS Status; + REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *FormsetPrivate; + + if (HiiHandle =3D=3D NULL || FormsetList =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + + FormsetPrivate =3D GetFormsetPrivateByHiiHandle (HiiHandle, FormsetList); + if (FormsetPrivate !=3D NULL) { + return EFI_ALREADY_STARTED; + } + + FormsetPrivate =3D NewFormsetPrivate (); + if (FormsetPrivate =3D=3D NULL) { + DEBUG ((DEBUG_ERROR, "%a, out of resource\n", __FUNCTION__)); + return EFI_OUT_OF_RESOURCES; + } + + // + // Load formset on the given HII handle. + // + Status =3D LoadFormset (HiiHandle, FormsetPrivate); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a, failed to load formset: %r\n", __FUNCTION__,= Status)); + FreePool (FormsetPrivate); + return Status; + } + + // + // Attach to cache list. + // + InsertTailList (FormsetList, &FormsetPrivate->Link); + + DEBUG_CODE ( + DumpFormsetList (FormsetList); + ); + + return EFI_SUCCESS; +} + +/** + Release formset list and all the forms that belong to this formset. + + @param[in] FormsetList Pointer to formst list that needs to be + released. + + @retval EFI_STATUS + +**/ +EFI_STATUS +ReleaseFormsetList ( + IN LIST_ENTRY *FormsetList + ) +{ + LIST_ENTRY *HiiFormsetLink; + LIST_ENTRY *HiiFormsetNextLink; + REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *HiiFormsetPrivate; + + if (FormsetList =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + + if (IsListEmpty (FormsetList)) { + return EFI_SUCCESS; + } + + HiiFormsetLink =3D GetFirstNode (FormsetList); + while (!IsNull (FormsetList, HiiFormsetLink)) { + HiiFormsetNextLink =3D GetNextNode (FormsetList, HiiFormsetLink); + HiiFormsetPrivate =3D REDFISH_PLATFORM_CONFIG_FORMSET_FROM_LINK (HiiFo= rmsetLink); + + // + // Detach from list. + // + RemoveEntryList (&HiiFormsetPrivate->Link); + ReleaseFormset (HiiFormsetPrivate); + FreePool (HiiFormsetPrivate); + HiiFormsetLink =3D HiiFormsetNextLink; + } + + return EFI_SUCCESS; +} + +/** + Get all pending list. + + @param[in] HiiHandle HII handle instance. + @param[in] PendingList Pending list to keep pending data. + + @retval REDFISH_PLATFORM_CONFIG_PENDING_LIST * Pointer to pending list= data. + +**/ +REDFISH_PLATFORM_CONFIG_PENDING_LIST * +GetPendingList ( + IN EFI_HII_HANDLE *HiiHandle, + IN LIST_ENTRY *PendingList + ) +{ + LIST_ENTRY *PendingListLink; + REDFISH_PLATFORM_CONFIG_PENDING_LIST *Target; + + if (HiiHandle =3D=3D NULL || PendingList =3D=3D NULL) { + return NULL; + } + + if (IsListEmpty (PendingList)) { + return NULL; + } + + PendingListLink =3D GetFirstNode (PendingList); + while (!IsNull (PendingList, PendingListLink)) { + Target =3D REDFISH_PLATFORM_CONFIG_PENDING_LIST_FROM_LINK (PendingList= Link); + + if (Target->HiiHandle =3D=3D HiiHandle) { + return Target; + } + + PendingListLink =3D GetNextNode (PendingList, PendingListLink); + } + + return NULL; +} + +/** + When HII database is updated. Keep updated HII handle into pending list = so + we can process them later. + + @param[in] HiiHandle HII handle instance. + @param[in] PendingList Pending list to keep HII handle which is recentl= y updated. + + @retval EFI_SUCCESS HII handle is saved in pending list. + @retval EFI_INVALID_PARAMETER HiiHnalde is NULL or PendingList is NULL. + @retval EFI_OUT_OF_RESOURCES System is out of memory. + +**/ +EFI_STATUS +NotifyFormsetUpdate ( + IN EFI_HII_HANDLE *HiiHandle, + IN LIST_ENTRY *PendingList + ) +{ + REDFISH_PLATFORM_CONFIG_PENDING_LIST *TargetPendingList; + + if (HiiHandle =3D=3D NULL || PendingList =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + + // + // Check and see if this HII handle is processed already. + // + TargetPendingList =3D GetPendingList (HiiHandle, PendingList); + if (TargetPendingList !=3D NULL) { + TargetPendingList->IsDeleted =3D FALSE; + DEBUG_CODE ( + DEBUG ((DEBUG_INFO, "%a, HII handle: 0x%x is updated\n", __FUNCTION__,= HiiHandle)); + ); + return EFI_SUCCESS; + } + + TargetPendingList=3D AllocateZeroPool (sizeof (REDFISH_PLATFORM_CONFIG_P= ENDING_LIST)); + if (TargetPendingList =3D=3D NULL) { + return EFI_OUT_OF_RESOURCES; + } + + TargetPendingList->HiiHandle =3D HiiHandle; + TargetPendingList->IsDeleted =3D FALSE; + + InsertTailList (PendingList, &TargetPendingList->Link); + + DEBUG_CODE ( + DEBUG ((DEBUG_INFO, "%a, HII handle: 0x%x is created\n", __FUNCTION__,= HiiHandle)); + ); + + return EFI_SUCCESS; +} + +/** + When HII database is updated and form-set is deleted. Keep deleted HII h= andle into pending list so + we can process them later. + + @param[in] HiiHandle HII handle instance. + @param[in] PendingList Pending list to keep HII handle which is recentl= y updated. + + @retval EFI_SUCCESS HII handle is saved in pending list. + @retval EFI_INVALID_PARAMETER HiiHnalde is NULL or PendingList is NULL. + @retval EFI_OUT_OF_RESOURCES System is out of memory. + +**/ +EFI_STATUS +NotifyFormsetDeleted ( + IN EFI_HII_HANDLE *HiiHandle, + IN LIST_ENTRY *PendingList + ) +{ + REDFISH_PLATFORM_CONFIG_PENDING_LIST *TargetPendingList; + + if (HiiHandle =3D=3D NULL || PendingList =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + + // + // Check and see if this HII handle is processed already. + // + TargetPendingList =3D GetPendingList (HiiHandle, PendingList); + if (TargetPendingList !=3D NULL) { + TargetPendingList->IsDeleted =3D TRUE; + DEBUG_CODE ( + DEBUG ((DEBUG_INFO, "%a, HII handle: 0x%x is updated and deleted\n",= __FUNCTION__, HiiHandle)); + ); + return EFI_SUCCESS; + } + + TargetPendingList=3D AllocateZeroPool (sizeof (REDFISH_PLATFORM_CONFIG_P= ENDING_LIST)); + if (TargetPendingList =3D=3D NULL) { + return EFI_OUT_OF_RESOURCES; + } + + TargetPendingList->HiiHandle =3D HiiHandle; + TargetPendingList->IsDeleted =3D TRUE; + + InsertTailList (PendingList, &TargetPendingList->Link); + + DEBUG_CODE ( + DEBUG ((DEBUG_INFO, "%a, HII handle: 0x%x is deleted\n", __FUNCTION__,= HiiHandle)); + ); + + return EFI_SUCCESS; +} + +/** + There are HII database update and we need to process them accordingly so= that we + won't use stale data. This function will parse updated HII handle again = in order + to get updated data-set. + + @param[in] FormsetList List to keep HII form-set. + @param[in] PendingList List to keep HII handle that is updated. + + @retval EFI_SUCCESS HII handle is saved in pending list. + @retval EFI_INVALID_PARAMETER FormsetList is NULL or PendingList is NU= LL. + +**/ +EFI_STATUS +ProcessPendingList ( + IN LIST_ENTRY *FormsetList, + IN LIST_ENTRY *PendingList + ) +{ + LIST_ENTRY *PendingListLink; + LIST_ENTRY *PendingListNextLink; + REDFISH_PLATFORM_CONFIG_PENDING_LIST *Target; + REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *FormsetPrivate; + EFI_STATUS Status; + + + if (FormsetList =3D=3D NULL || PendingList =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + + if (IsListEmpty (PendingList)) { + return EFI_SUCCESS; + } + + PendingListLink =3D GetFirstNode (PendingList); + while (!IsNull (PendingList, PendingListLink)) { + PendingListNextLink =3D GetNextNode (PendingList, PendingListLink); + Target =3D REDFISH_PLATFORM_CONFIG_PENDING_LIST_FROM_LINK (PendingList= Link); + + if (Target->IsDeleted) { + // + // The HII resource on this HII handle is removed. Release the forms= et. + // + FormsetPrivate =3D GetFormsetPrivateByHiiHandle (Target->HiiHandle, = FormsetList); + if (FormsetPrivate !=3D NULL) { + DEBUG ((DEBUG_INFO, "%a, formset: %g is removed because driver rel= ease HII resource it already\n", __FUNCTION__, FormsetPrivate->Guid)); + RemoveEntryList (&FormsetPrivate->Link); + ReleaseFormset (FormsetPrivate); + FreePool (FormsetPrivate); + } else { + DEBUG ((DEBUG_WARN, "%a, formset on HII handle 0x%x was removed al= ready\n", __FUNCTION__, Target->HiiHandle)); + } + } else { + // + // The HII resource on this HII handle is updated/removed. + // + FormsetPrivate =3D GetFormsetPrivateByHiiHandle (Target->HiiHandle, = FormsetList); + if (FormsetPrivate !=3D NULL) { + // + // HII formset already exist, release it and query again. + // + DEBUG ((DEBUG_INFO, "%a, formset: %g is updated. Release current f= ormset\n", __FUNCTION__, &FormsetPrivate->Guid)); + RemoveEntryList (&FormsetPrivate->Link); + ReleaseFormset (FormsetPrivate); + FreePool (FormsetPrivate); + } + + Status =3D LoadFormsetList (Target->HiiHandle, FormsetList); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a, load formset from HII handle: 0x%x faile= d: %r\n", __FUNCTION__, Target->HiiHandle, Status)); + } + } + + // + // Detach it from list first. + // + RemoveEntryList (&Target->Link); + FreePool (Target); + + PendingListLink =3D PendingListNextLink; + } + + return EFI_SUCCESS; +} + +/** + Release all resource in statement list. + + @param[in] StatementList Statement list to be released. + + @retval EFI_SUCCESS All resource are released. + @retval EFI_INVALID_PARAMETER StatementList is NULL. + +**/ +EFI_STATUS +ReleaseStatementList ( + IN REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_LIST *StatementList + ) +{ + REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_REF *StatementRef; + LIST_ENTRY *NextLink; + + if (StatementList =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + + if (IsListEmpty (&StatementList->StatementList)) { + return EFI_SUCCESS; + } + + NextLink =3D GetFirstNode (&StatementList->StatementList); + while (!IsNull (&StatementList->StatementList, NextLink)) { + StatementRef =3D REDFISH_PLATFORM_CONFIG_STATEMENT_REF_FROM_LINK (Next= Link); + NextLink =3D GetNextNode (&StatementList->StatementList, NextLink); + + RemoveEntryList (&StatementRef->Link); + FreePool (StatementRef); + } + + return EFI_SUCCESS; +} diff --git a/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigImpl.= h b/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigImpl.h index e0ba0fb2d3..cd7a52aef3 100644 --- a/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigImpl.h +++ b/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigImpl.h @@ -1,274 +1,297 @@ -/** @file - This file defines the EDKII Redfish Platform Config Protocol interface. - - (C) Copyright 2021 Hewlett Packard Enterprise Development LP
- - SPDX-License-Identifier: BSD-2-Clause-Patent - -**/ - -#ifndef EDKII_REDFISH_PLATFORM_CONFIG_IMPL_H_ -#define EDKII_REDFISH_PLATFORM_CONFIG_IMPL_H_ - -#include - -// -// Libraries -// -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define REDFISH_PLATFORM_CONFIG_DELETE_EXPIRED_FORMSET 0x00 -#define IS_EMPTY_STRING(a) (a =3D=3D NULL ||= a[0] =3D=3D L'\0') -#define ENGLISH_LANGUAGE_CODE "en-US" -#define X_UEFI_SCHEMA_PREFIX "x-uefi-redfish-" - -// -// Definition of REDFISH_PLATFORM_CONFIG_PRIVATE. -// -typedef struct { - LIST_ENTRY Link; - EFI_HII_HANDLE HiiHandle; - BOOLEAN IsDeleted; -} REDFISH_PLATFORM_CONFIG_PENDING_LIST; - -#define REDFISH_PLATFORM_CONFIG_PENDING_LIST_FROM_LINK(a) BASE_CR (a, RED= FISH_PLATFORM_CONFIG_PENDING_LIST, Link) - -typedef struct { - UINTN Count; // Number of schema in list - CHAR8 **SchemaList; // Schema list -} REDFISH_PLATFORM_CONFIG_SCHEMA; - -// -// Definition of REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE -// -typedef struct { - LIST_ENTRY Link; - HII_FORMSET *HiiFormSet; // Pointer to HII forms= et data. - EFI_GUID Guid; // Formset GUID. - EFI_HII_HANDLE HiiHandle; // Hii Handle of this f= ormset. - LIST_ENTRY HiiFormList; // Form list that keep = form data under this formset. - CHAR16 *DevicePathStr; // Device path of this = formset. - REDFISH_PLATFORM_CONFIG_SCHEMA SupportedSchema; // Schema that is suppo= rted in this formset. -} REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE; - -#define REDFISH_PLATFORM_CONFIG_FORMSET_FROM_LINK(a) BASE_CR (a, REDFISH_= PLATFORM_CONFIG_FORM_SET_PRIVATE, Link) - -// -// Definition of REDFISH_PLATFORM_CONFIG_FORM_PRIVATE -// -typedef struct { - LIST_ENTRY Link; - UINT16 Id; // Form ID. - EFI_STRING_ID Title; // String toke= n of form title. - REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *ParentFormset; - HII_FORM *HiiForm; // Pointer to = HII form data. - LIST_ENTRY StatementList; // Statement l= ist that keep statement under this form. -} REDFISH_PLATFORM_CONFIG_FORM_PRIVATE; - -#define REDFISH_PLATFORM_CONFIG_FORM_FROM_LINK(a) BASE_CR (a, REDFISH_PLA= TFORM_CONFIG_FORM_PRIVATE, Link) - -// -// Definition of REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE -// -typedef struct { - LIST_ENTRY Link; - REDFISH_PLATFORM_CONFIG_FORM_PRIVATE *ParentForm; - HII_STATEMENT *HiiStatement; // Pointer to HII = statement data. - EFI_QUESTION_ID QuestionId; // Question ID of = this statement. - EFI_STRING_ID Description; // String token of= this question. - EFI_STRING DesStringCache; // The string cach= e for search function. -} REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE; - -#define REDFISH_PLATFORM_CONFIG_STATEMENT_FROM_LINK(a) BASE_CR (a, REDFIS= H_PLATFORM_CONFIG_STATEMENT_PRIVATE, Link) - -// -// Definition of REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_REF -// -typedef struct { - LIST_ENTRY Link; - REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE *Statement; -} REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_REF; - -#define REDFISH_PLATFORM_CONFIG_STATEMENT_REF_FROM_LINK(a) BASE_CR (a, RE= DFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_REF, Link) - -// -// Definition of REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_LIST -// -typedef struct { - LIST_ENTRY StatementList; // List of REDFISH_PLATFORM_CONFIG_STA= TEMENT_PRIVATE_REF - UINTN Count; -} REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_LIST; - -/** - Release formset list and all the forms that belong to this formset. - - @param[in] FormsetList Pointer to formst list that needs to be - released. - - @retval EFI_STATUS - -**/ -EFI_STATUS -ReleaseFormsetList ( - IN LIST_ENTRY *FormsetList - ); - -/** - Release formset list and all the forms that belong to this formset. - - @param[in] FormsetList Pointer to formst list that needs to be - released. - - @retval EFI_STATUS - -**/ -EFI_STATUS -LoadFormsetList ( - IN EFI_HII_HANDLE *HiiHandle, - OUT LIST_ENTRY *FormsetList - ); - -/** - When HII database is updated. Keep updated HII handle into pending list = so - we can process them later. - - @param[in] HiiHandle HII handle instance. - @param[in] PendingList Pending list to keep HII handle which is recentl= y updated. - - @retval EFI_SUCCESS HII handle is saved in pending list. - @retval EFI_INVALID_PARAMETER HiiHnalde is NULL or PendingList is NULL. - @retval EFI_OUT_OF_RESOURCES System is out of memory. - -**/ -EFI_STATUS -NotifyFormsetUpdate ( - IN EFI_HII_HANDLE *HiiHandle, - IN LIST_ENTRY *PendingList - ); - -/** - When HII database is updated and form-set is deleted. Keep deleted HII h= andle into pending list so - we can process them later. - - @param[in] HiiHandle HII handle instance. - @param[in] PendingList Pending list to keep HII handle which is recentl= y updated. - - @retval EFI_SUCCESS HII handle is saved in pending list. - @retval EFI_INVALID_PARAMETER HiiHnalde is NULL or PendingList is NULL. - @retval EFI_OUT_OF_RESOURCES System is out of memory. - -**/ -EFI_STATUS -NotifyFormsetDeleted ( - IN EFI_HII_HANDLE *HiiHandle, - IN LIST_ENTRY *PendingList - ); - -/** - Get statement private instance by the given configure language. - - @param[in] FormsetList Form-set list to search. - @param[in] Schema Schema to be matched. - @param[in] ConfigureLang Configure language. - - @retval REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE * Pointer to stateme= nt private instance. - -**/ -REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE * -GetStatementPrivateByConfigureLang ( - IN LIST_ENTRY *FormsetList, - IN CHAR8 *Schema, - IN EFI_STRING ConfigureLang - ); - -/** - Search and find statement private instance by given regular expression p= atthern - which describes the Configure Language. - - @param[in] RegularExpressionProtocol Regular express protocol. - @param[in] FormsetList Form-set list to search. - @param[in] Schema Schema to be matched. - @param[in] Pattern Regular expression pattern. - @param[out] StatementList Statement list that match above = pattern. - - @retval EFI_SUCCESS Statement list is returned. - @retval EFI_INVALID_PARAMETER Input parameter is NULL. - @retval EFI_NOT_READY Regular express protocol is NULL. - @retval EFI_NOT_FOUND No statement is found. - @retval EFI_OUT_OF_RESOURCES System is out of memory. - -**/ -EFI_STATUS -GetStatementPrivateByConfigureLangRegex ( - IN EFI_REGULAR_EXPRESSION_PROTOCOL *RegularExpressionPr= otocol, - IN LIST_ENTRY *FormsetList, - IN CHAR8 *Schema, - IN EFI_STRING Pattern, - OUT REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_LIST *StatementList - ); - -/** - There are HII database update and we need to process them accordingly so= that we - won't use stale data. This function will parse updated HII handle again = in order - to get updated data-set. - - @param[in] FormsetList List to keep HII form-set. - @param[in] PendingList List to keep HII handle that is updated. - - @retval EFI_SUCCESS HII handle is saved in pending list. - @retval EFI_INVALID_PARAMETER FormsetList is NULL or PendingList is NU= LL. - -**/ -EFI_STATUS -ProcessPendingList ( - IN LIST_ENTRY *FormsetList, - IN LIST_ENTRY *PendingList - ); - -/** - Retrieves a string from a string package in a English language. The - returned string is allocated using AllocatePool(). The caller is respon= sible - for freeing the allocated buffer using FreePool(). - - If HiiHandle is NULL, then ASSERT(). - If StringId is 0, then ASSET. - - @param[in] HiiStringProtocol EFI_HII_STRING_PROTOCOL instance. - @param[in] HiiHandle A handle that was previously registered in= the HII Database. - @param[in] StringId The identifier of the string to retrieved = from the string - package associated with HiiHandle. - - @retval NULL The string specified by StringId is not present in the st= ring package. - @retval Other The string was returned. - -**/ -EFI_STRING -HiiGetRedfishString ( - IN EFI_HII_HANDLE HiiHandle, - IN CHAR8 *Language, - IN EFI_STRING_ID StringId - ); - -/** - Release all resource in statement list. - - @param[in] StatementList Statement list to be released. - - @retval EFI_SUCCESS All resource are released. - @retval EFI_INVALID_PARAMETER StatementList is NULL. - -**/ -EFI_STATUS -ReleaseStatementList ( - IN REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_LIST *StatementList - ); - -#endif +/** @file + This file defines the EDKII Redfish Platform Config Protocol interface. + + (C) Copyright 2021-2022 Hewlett Packard Enterprise Development LP
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef EDKII_REDFISH_PLATFORM_CONFIG_IMPL_H_ +#define EDKII_REDFISH_PLATFORM_CONFIG_IMPL_H_ + +#include + +// +// Libraries +// +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define IS_EMPTY_STRING(a) (a =3D=3D NULL ||= a[0] =3D=3D L'\0') +#define ENGLISH_LANGUAGE_CODE "en-US" +#define X_UEFI_SCHEMA_PREFIX "x-uefi-redfish-" + +// +// Definition of REDFISH_PLATFORM_CONFIG_PRIVATE. +// +typedef struct { + LIST_ENTRY Link; + EFI_HII_HANDLE HiiHandle; + BOOLEAN IsDeleted; +} REDFISH_PLATFORM_CONFIG_PENDING_LIST; + +#define REDFISH_PLATFORM_CONFIG_PENDING_LIST_FROM_LINK(a) BASE_CR (a, RED= FISH_PLATFORM_CONFIG_PENDING_LIST, Link) + +typedef struct { + UINTN Count; // Number of schema in list + CHAR8 **SchemaList; // Schema list +} REDFISH_PLATFORM_CONFIG_SCHEMA; + +// +// Definition of REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE +// +typedef struct { + LIST_ENTRY Link; + HII_FORMSET *HiiFormSet; // Pointer to HII forms= et data. + EFI_GUID Guid; // Formset GUID. + EFI_HII_HANDLE HiiHandle; // Hii Handle of this f= ormset. + LIST_ENTRY HiiFormList; // Form list that keep = form data under this formset. + CHAR16 *DevicePathStr; // Device path of this = formset. + REDFISH_PLATFORM_CONFIG_SCHEMA SupportedSchema; // Schema that is suppo= rted in this formset. +} REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE; + +#define REDFISH_PLATFORM_CONFIG_FORMSET_FROM_LINK(a) BASE_CR (a, REDFISH_= PLATFORM_CONFIG_FORM_SET_PRIVATE, Link) + +// +// Definition of REDFISH_PLATFORM_CONFIG_FORM_PRIVATE +// +typedef struct { + LIST_ENTRY Link; + UINT16 Id; // Form ID. + EFI_STRING_ID Title; // String toke= n of form title. + REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *ParentFormset; + HII_FORM *HiiForm; // Pointer to = HII form data. + LIST_ENTRY StatementList; // Statement l= ist that keep statement under this form. +} REDFISH_PLATFORM_CONFIG_FORM_PRIVATE; + +#define REDFISH_PLATFORM_CONFIG_FORM_FROM_LINK(a) BASE_CR (a, REDFISH_PLA= TFORM_CONFIG_FORM_PRIVATE, Link) + +// +// Definition of REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE +// +typedef struct { + LIST_ENTRY Link; + REDFISH_PLATFORM_CONFIG_FORM_PRIVATE *ParentForm; + HII_STATEMENT *HiiStatement; // Pointer to HII = statement data. + EFI_QUESTION_ID QuestionId; // Question ID of = this statement. + EFI_STRING_ID Description; // String token of= this question. + EFI_STRING DesStringCache; // The string cach= e for search function. +} REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE; + +#define REDFISH_PLATFORM_CONFIG_STATEMENT_FROM_LINK(a) BASE_CR (a, REDFIS= H_PLATFORM_CONFIG_STATEMENT_PRIVATE, Link) + +// +// Definition of REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_REF +// +typedef struct { + LIST_ENTRY Link; + REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE *Statement; +} REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_REF; + +#define REDFISH_PLATFORM_CONFIG_STATEMENT_REF_FROM_LINK(a) BASE_CR (a, RE= DFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_REF, Link) + +// +// Definition of REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_LIST +// +typedef struct { + LIST_ENTRY StatementList; // List of REDFISH_PLATFORM_CONFIG_STA= TEMENT_PRIVATE_REF + UINTN Count; +} REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_LIST; + +/** + Release formset list and all the forms that belong to this formset. + + @param[in] FormsetList Pointer to formst list that needs to be + released. + + @retval EFI_STATUS + +**/ +EFI_STATUS +ReleaseFormsetList ( + IN LIST_ENTRY *FormsetList + ); + +/** + Release formset list and all the forms that belong to this formset. + + @param[in] FormsetList Pointer to formst list that needs to be + released. + + @retval EFI_STATUS + +**/ +EFI_STATUS +LoadFormsetList ( + IN EFI_HII_HANDLE *HiiHandle, + OUT LIST_ENTRY *FormsetList + ); + +/** + When HII database is updated. Keep updated HII handle into pending list = so + we can process them later. + + @param[in] HiiHandle HII handle instance. + @param[in] PendingList Pending list to keep HII handle which is recentl= y updated. + + @retval EFI_SUCCESS HII handle is saved in pending list. + @retval EFI_INVALID_PARAMETER HiiHnalde is NULL or PendingList is NULL. + @retval EFI_OUT_OF_RESOURCES System is out of memory. + +**/ +EFI_STATUS +NotifyFormsetUpdate ( + IN EFI_HII_HANDLE *HiiHandle, + IN LIST_ENTRY *PendingList + ); + +/** + When HII database is updated and form-set is deleted. Keep deleted HII h= andle into pending list so + we can process them later. + + @param[in] HiiHandle HII handle instance. + @param[in] PendingList Pending list to keep HII handle which is recentl= y updated. + + @retval EFI_SUCCESS HII handle is saved in pending list. + @retval EFI_INVALID_PARAMETER HiiHnalde is NULL or PendingList is NULL. + @retval EFI_OUT_OF_RESOURCES System is out of memory. + +**/ +EFI_STATUS +NotifyFormsetDeleted ( + IN EFI_HII_HANDLE *HiiHandle, + IN LIST_ENTRY *PendingList + ); + +/** + Get statement private instance by the given configure language. + + @param[in] FormsetList Form-set list to search. + @param[in] Schema Schema to be matched. + @param[in] ConfigureLang Configure language. + + @retval REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE * Pointer to stateme= nt private instance. + +**/ +REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE * +GetStatementPrivateByConfigureLang ( + IN LIST_ENTRY *FormsetList, + IN CHAR8 *Schema, + IN EFI_STRING ConfigureLang + ); + +/** + Search and find statement private instance by given regular expression p= atthern + which describes the Configure Language. + + @param[in] RegularExpressionProtocol Regular express protocol. + @param[in] FormsetList Form-set list to search. + @param[in] Schema Schema to be matched. + @param[in] Pattern Regular expression pattern. + @param[out] StatementList Statement list that match above = pattern. + + @retval EFI_SUCCESS Statement list is returned. + @retval EFI_INVALID_PARAMETER Input parameter is NULL. + @retval EFI_NOT_READY Regular express protocol is NULL. + @retval EFI_NOT_FOUND No statement is found. + @retval EFI_OUT_OF_RESOURCES System is out of memory. + +**/ +EFI_STATUS +GetStatementPrivateByConfigureLangRegex ( + IN EFI_REGULAR_EXPRESSION_PROTOCOL *RegularExpressionPr= otocol, + IN LIST_ENTRY *FormsetList, + IN CHAR8 *Schema, + IN EFI_STRING Pattern, + OUT REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_LIST *StatementList + ); + +/** + There are HII database update and we need to process them accordingly so= that we + won't use stale data. This function will parse updated HII handle again = in order + to get updated data-set. + + @param[in] FormsetList List to keep HII form-set. + @param[in] PendingList List to keep HII handle that is updated. + + @retval EFI_SUCCESS HII handle is saved in pending list. + @retval EFI_INVALID_PARAMETER FormsetList is NULL or PendingList is NU= LL. + +**/ +EFI_STATUS +ProcessPendingList ( + IN LIST_ENTRY *FormsetList, + IN LIST_ENTRY *PendingList + ); + +/** + Retrieves a unicode string from a string package in a given language. The + returned string is allocated using AllocatePool(). The caller is respon= sible + for freeing the allocated buffer using FreePool(). + + If HiiHandle is NULL, then ASSERT(). + If StringId is 0, then ASSET. + + @param[in] HiiHandle A handle that was previously registered in= the HII Database. + @param[in] Language The specified configure language to get st= ring. + @param[in] StringId The identifier of the string to retrieved = from the string + package associated with HiiHandle. + + @retval NULL The string specified by StringId is not present in the st= ring package. + @retval Other The string was returned. + +**/ +EFI_STRING +HiiGetRedfishString ( + IN EFI_HII_HANDLE HiiHandle, + IN CHAR8 *Language, + IN EFI_STRING_ID StringId + ); + +/** + Retrieves a ASCII string from a string package in a given language. The + returned string is allocated using AllocatePool(). The caller is respon= sible + for freeing the allocated buffer using FreePool(). + + If HiiHandle is NULL, then ASSERT(). + If StringId is 0, then ASSET. + + @param[in] HiiHandle A handle that was previously registered in= the HII Database. + @param[in] Language The specified configure language to get st= ring. + @param[in] StringId The identifier of the string to retrieved = from the string + package associated with HiiHandle. + + @retval NULL The string specified by StringId is not present in the st= ring package. + @retval Other The string was returned. + +**/ +CHAR8 * +HiiGetRedfishAsciiString ( + IN EFI_HII_HANDLE HiiHandle, + IN CHAR8 *Language, + IN EFI_STRING_ID StringId + ); + +/** + Release all resource in statement list. + + @param[in] StatementList Statement list to be released. + + @retval EFI_SUCCESS All resource are released. + @retval EFI_INVALID_PARAMETER StatementList is NULL. + +**/ +EFI_STATUS +ReleaseStatementList ( + IN REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_LIST *StatementList + ); + +#endif --=20 2.32.0.windows.2 -=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 (#91795): https://edk2.groups.io/g/devel/message/91795 Mute This Topic: https://groups.io/mt/92598008/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-