* [edk2-staging][PATCH v2 1/1] edk2/RedfishPkg: Update Redfish Platform Config Protocol
@ 2022-07-24 13:19 Nickle Wang
2022-07-24 13:46 ` Chang, Abner
0 siblings, 1 reply; 3+ messages in thread
From: Nickle Wang @ 2022-07-24 13:19 UTC (permalink / raw)
To: devel; +Cc: Abner Chang, Yang Atom, Nick Ramirez
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 <nickle.wang@hpe.com>
Cc: Abner Chang <abner.chang@amd.com>
Cc: Yang Atom <Atom.Yang@amd.com>
Cc: Nick Ramirez <nramirez@nvidia.com>
---
.../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/RedfishPkg/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<BR>
-
- 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_PLATFORM_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 = 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_CONFIG_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 configure 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_CONFIG_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 configure 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 given Schema and Pattern.
-
- @param[in] This Pointer to EDKII_REDFISH_PLATFORM_CONFIG_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 ConfigureLangList.
-
- @retval EFI_SUCCESS ConfigureLangList is returned successfully.
- @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_CONFIG_PROTOCOL instance.
- @param[in] HiiHandle The target handle to search. If handle is NULL,
- this function returns all schema from HII database.
- @param[out] SupportedSchema The supported schema list which is separated 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 using 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, OPTIONAL
- 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<BR>
+
+ 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_PLATFORM_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 = 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_CONFIG_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 configure 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_CONFIG_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 configure 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 given Schema and RegexPattern.
+
+ @param[in] This Pointer to EDKII_REDFISH_PLATFORM_CONFIG_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 ConfigureLangList.
+
+ @retval EFI_SUCCESS ConfigureLangList is returned successfully.
+ @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_CONFIG_PROTOCOL instance.
+ @param[in] HiiHandle The target handle to search. If handle is NULL,
+ this function returns all schema from HII database.
+ @param[out] SupportedSchema The supported schema list which is separated 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 using 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, OPTIONAL
+ 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<BR>
-
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#include "RedfishPlatformConfigDxe.h"
-#include "RedfishPlatformConfigImpl.h"
-
-REDFISH_PLATFORM_CONFIG_PRIVATE *mRedfishPlatformConfigPrivate = 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 second value.
- -1 is returned when second value is greater than first value.
-
-**/
-UINTN
-CompareHiiStatementValue (
- IN HII_STATEMENT_VALUE *Value1,
- IN HII_STATEMENT_VALUE *Value2
- )
-{
- INTN Result;
- UINT64 Data1;
- UINT64 Data2;
-
- if (Value1 == NULL || Value2 == NULL) {
- return 0xFF;
- }
-
- switch (Value1->Type) {
- case EFI_IFR_TYPE_NUM_SIZE_8:
- Data1 = Value1->Value.u8;
- break;
- case EFI_IFR_TYPE_NUM_SIZE_16:
- Data1 = Value1->Value.u16;
- break;
- case EFI_IFR_TYPE_NUM_SIZE_32:
- Data1 = Value1->Value.u32;
- break;
- case EFI_IFR_TYPE_NUM_SIZE_64:
- Data1 = Value1->Value.u64;
- break;
- case EFI_IFR_TYPE_BOOLEAN:
- Data1 = (Value1->Value.b ? 1 : 0);
- break;
- default:
- return 0xFF;
- }
-
- switch (Value2->Type) {
- case EFI_IFR_TYPE_NUM_SIZE_8:
- Data2 = Value2->Value.u8;
- break;
- case EFI_IFR_TYPE_NUM_SIZE_16:
- Data2 = Value2->Value.u16;
- break;
- case EFI_IFR_TYPE_NUM_SIZE_32:
- Data2 = Value2->Value.u32;
- break;
- case EFI_IFR_TYPE_NUM_SIZE_64:
- Data2 = Value2->Value.u64;
- break;
- case EFI_IFR_TYPE_BOOLEAN:
- Data2 = (Value2->Value.b ? 1 : 0);
- break;
- default:
- return 0xFF;
- }
-
- Result = (Data1 == 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 != EFI_IFR_ONE_OF_OP) {
- return 0;
- }
-
- if (IsListEmpty (&Statement->HiiStatement->OptionListHead)) {
- return 0;
- }
-
- Link = GetFirstNode (&Statement->HiiStatement->OptionListHead);
- while (!IsNull (&Statement->HiiStatement->OptionListHead, Link)) {
- Option = HII_QUESTION_OPTION_FROM_LINK (Link);
-
- if (CompareHiiStatementValue (&Statement->HiiStatement->Value, &Option->Value) == 0) {
- return Option->Text;
- }
-
- Link = 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 == NULL || IS_EMPTY_STRING (HiiString) || Value == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- if (Statement->HiiStatement->Operand != EFI_IFR_ONE_OF_OP) {
- return EFI_UNSUPPORTED;
- }
-
- if (IsListEmpty (&Statement->HiiStatement->OptionListHead)) {
- return EFI_NOT_FOUND;
- }
-
- Found = FALSE;
- Link = GetFirstNode (&Statement->HiiStatement->OptionListHead);
- while (!IsNull (&Statement->HiiStatement->OptionListHead, Link)) {
- Option = HII_QUESTION_OPTION_FROM_LINK (Link);
-
- TmpString = HiiGetRedfishString (Statement->ParentForm->ParentFormset->HiiHandle, Schema, Option->Text);
- if (TmpString != NULL) {
- if (StrCmp (TmpString, HiiString) == 0) {
- CopyMem (Value, &Option->Value, sizeof (HII_STATEMENT_VALUE));
- Found = TRUE;
- }
- FreePool (TmpString);
- }
-
- if (Found) {
- return EFI_SUCCESS;
- }
-
- Link = 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 == NULL || RedfishValue == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- switch (Value->Type) {
- case EFI_IFR_TYPE_NUM_SIZE_8:
- RedfishValue->Type = REDFISH_VALUE_TYPE_INTEGER;
- RedfishValue->Value.Integer = (INT64)Value->Value.u8;
- break;
- case EFI_IFR_TYPE_NUM_SIZE_16:
- RedfishValue->Type = REDFISH_VALUE_TYPE_INTEGER;
- RedfishValue->Value.Integer = (INT64)Value->Value.u16;
- break;
- case EFI_IFR_TYPE_NUM_SIZE_32:
- RedfishValue->Type = REDFISH_VALUE_TYPE_INTEGER;
- RedfishValue->Value.Integer = (INT64)Value->Value.u32;
- break;
- case EFI_IFR_TYPE_NUM_SIZE_64:
- RedfishValue->Type = REDFISH_VALUE_TYPE_INTEGER;
- RedfishValue->Value.Integer = (INT64)Value->Value.u64;
- break;
- case EFI_IFR_TYPE_BOOLEAN:
- RedfishValue->Type = REDFISH_VALUE_TYPE_BOOLEAN;
- RedfishValue->Value.Boolean = Value->Value.b;
- break;
- default:
- RedfishValue->Type = 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 == NULL || RedfishValue == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- switch (RedfishValue->Type) {
- case REDFISH_VALUE_TYPE_INTEGER:
- Value->Type = EFI_IFR_TYPE_NUM_SIZE_64;
- Value->Value.u64 = (UINT64)RedfishValue->Value.Integer;
- break;
- case REDFISH_VALUE_TYPE_BOOLEAN:
- Value->Type = EFI_IFR_TYPE_BOOLEAN;
- Value->Value.b = RedfishValue->Value.Boolean;
- break;
- default:
- Value->Type = 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 = AsciiStrSize(CONFIGURE_LANGUAGE_PREFIX) + AsciiStrSize (Schema) + AsciiStrSize (Version);
-
- FullName = AllocatePool (Size);
- if (FullName == NULL) {
- DEBUG ((DEBUG_ERROR, "%a, out-of-resource\n", __FUNCTION__));
- return NULL;
- }
-
- AsciiSPrint (FullName, Size, "%a%a.%a", CONFIGURE_LANGUAGE_PREFIX, Schema, 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 refers 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 *RedfishPlatformConfigPrivate,
- 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 == NULL || IS_EMPTY_STRING (Schema) || IS_EMPTY_STRING (ConfigureLang) || Statement == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- *Statement = NULL;
-
- Status = ProcessPendingList (&RedfishPlatformConfigPrivate->FormsetList, &RedfishPlatformConfigPrivate->PendingList);
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "%a, ProcessPendingList failure: %r\n", __FUNCTION__, Status));
- return Status;
- }
-
- TargetStatement = GetStatementPrivateByConfigureLang (&RedfishPlatformConfigPrivate->FormsetList, Schema, ConfigureLang);
- if (TargetStatement == 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 = 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 == EFI_IFR_TYPE_UNDEFINED) {
- return EFI_DEVICE_ERROR;
- }
-
- //
- // Return Value.
- //
- *Statement = TargetStatement;
-
- return EFI_SUCCESS;
-}
-
-/**
- Get Redfish value with the given Schema and Configure Language.
-
- @param[in] This Pointer to EDKII_REDFISH_PLATFORM_CONFIG_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 configure 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 == NULL || IS_EMPTY_STRING (Schema) || IS_EMPTY_STRING (Version) || IS_EMPTY_STRING (ConfigureLang) || Value == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- RedfishPlatformConfigPrivate = REDFISH_PLATFORM_CONFIG_PRIVATE_FROM_THIS (This);
- Value->Type = REDFISH_VALUE_TYPE_UNKNOWN;
- FullSchema = NULL;
- HiiString = NULL;
-
- FullSchema = GetFullSchemaString (Schema, Version);
- if (FullSchema == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
-
- Status = RedfishPlatformConfigGetStatementCommon (RedfishPlatformConfigPrivate, FullSchema, ConfigureLang, &TargetStatement);
- if (EFI_ERROR (Status)) {
- goto RELEASE_RESOURCE;
- }
-
- switch (TargetStatement->HiiStatement->Operand) {
- case EFI_IFR_ONE_OF_OP:
- StringId = HiiValueToOneOfOptionStringId (TargetStatement);
- if (StringId == 0) {
- ASSERT (FALSE);
- Status = EFI_DEVICE_ERROR;
- goto RELEASE_RESOURCE;
- }
-
- HiiString = HiiGetRedfishString (TargetStatement->ParentForm->ParentFormset->HiiHandle, FullSchema, StringId);
- if (HiiString == NULL) {
- DEBUG ((DEBUG_ERROR, "%a, Can not find string ID: 0x%x with %a\n", __FUNCTION__, StringId, FullSchema));
- Status = EFI_NOT_FOUND;
- goto RELEASE_RESOURCE;
- }
-
- Size = StrLen (HiiString) + 1;
- Value->Value.Buffer = AllocatePool (Size);
- if (Value->Value.Buffer == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- goto RELEASE_RESOURCE;
- }
-
- UnicodeStrToAsciiStrS (HiiString, Value->Value.Buffer, Size);
- Value->Type = REDFISH_VALUE_TYPE_STRING;
-
- break;
- case EFI_IFR_STRING_OP:
- if (TargetStatement->HiiStatement->Value.Type != EFI_IFR_TYPE_STRING) {
- ASSERT (FALSE);
- Status = EFI_DEVICE_ERROR;
- goto RELEASE_RESOURCE;
- }
-
- Value->Type = REDFISH_VALUE_TYPE_STRING;
- Value->Value.Buffer = AllocateCopyPool (StrSize ((CHAR16 *)TargetStatement->HiiStatement->Value.Buffer), TargetStatement->HiiStatement->Value.Buffer);
- if (Value->Value.Buffer == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- goto RELEASE_RESOURCE;
- }
- break;
- case EFI_IFR_CHECKBOX_OP:
- case EFI_IFR_NUMERIC_OP:
- Status = HiiValueToRedfishNumeric (&TargetStatement->HiiStatement->Value, Value);
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "%a, failed to convert HII value to Redfish value: %r\n", __FUNCTION__, Status));
- goto RELEASE_RESOURCE;
- }
- break;
- default:
- DEBUG ((DEBUG_ERROR, "%a, catch unsupported type: 0x%x! Please contact with author if we need to support this type.\n", __FUNCTION__, TargetStatement->HiiStatement->Operand));
- ASSERT (FALSE);
- Status = EFI_UNSUPPORTED;
- goto RELEASE_RESOURCE;
- }
-
-RELEASE_RESOURCE:
-
- if (FullSchema != NULL) {
- FreePool (FullSchema);
- }
-
- if (HiiString != 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 == NULL || HiiForm == NULL || HiiStatement == NULL || Value == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- Status = SetQuestionValue (
- HiiFormset,
- HiiForm,
- HiiStatement,
- Value
- );
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "%a, failed to set question value: %r\n", __FUNCTION__, Status));
- return Status;
- }
-
- Status = 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 refers 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 == NULL || IS_EMPTY_STRING (Schema) || IS_EMPTY_STRING (ConfigureLang) || StatementValue == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- TempBuffer = NULL;
-
- Status = ProcessPendingList (&RedfishPlatformConfigPrivate->FormsetList, &RedfishPlatformConfigPrivate->PendingList);
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "%a, ProcessPendingList failure: %r\n", __FUNCTION__, Status));
- return Status;
- }
-
- TargetStatement = GetStatementPrivateByConfigureLang (&RedfishPlatformConfigPrivate->FormsetList, Schema, ConfigureLang);
- if (TargetStatement == 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 != 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 == EFI_IFR_ONE_OF_OP && StatementValue->Type == EFI_IFR_TYPE_STRING) {
- TempBuffer = AllocatePool (StatementValue->BufferLen * sizeof (CHAR16));
- if (TempBuffer == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
-
- AsciiStrToUnicodeStrS (StatementValue->Buffer, TempBuffer, StatementValue->BufferLen);
- FreePool (StatementValue->Buffer);
- StatementValue->Buffer = NULL;
- StatementValue->BufferLen = 0;
-
- Status = HiiStringToOneOfOptionValue (TargetStatement, Schema, TempBuffer, 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 == EFI_IFR_NUMERIC_OP && StatementValue->Type == EFI_IFR_TYPE_NUM_SIZE_64) {
- //
- // Redfish only has numeric value type and it does not care about the value size.
- // Do a patch here so we have proper value size applied.
- //
- StatementValue->Type = 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, TargetStatement->HiiStatement->Value.Type));
- ASSERT (FALSE);
- }
- }
-
- Status = 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", __FUNCTION__, Status));
- return Status;
- }
-
- return EFI_SUCCESS;
-}
-
-/**
- Set Redfish value with the given Schema and Configure Language.
-
- @param[in] This Pointer to EDKII_REDFISH_PLATFORM_CONFIG_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 configure 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 == NULL || IS_EMPTY_STRING (Schema) || IS_EMPTY_STRING (Version) || IS_EMPTY_STRING (ConfigureLang)) {
- return EFI_INVALID_PARAMETER;
- }
-
- if (Value.Type == REDFISH_VALUE_TYPE_UNKNOWN || Value.Type >= REDFISH_VALUE_TYPE_MAX) {
- return EFI_INVALID_PARAMETER;
- }
-
- RedfishPlatformConfigPrivate = REDFISH_PLATFORM_CONFIG_PRIVATE_FROM_THIS (This);
- FullSchema = NULL;
-
- FullSchema = GetFullSchemaString (Schema, Version);
- if (FullSchema == 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 = RedfishNumericToHiiValue (&Value, &NewValue);
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "%a, failed to convert Redfish value to Hii value: %r\n", __FUNCTION__, Status));
- goto RELEASE_RESOURCE;
- }
- break;
- case REDFISH_VALUE_TYPE_STRING:
- NewValue.Type = EFI_IFR_TYPE_STRING;
- NewValue.BufferLen = (UINT16)AsciiStrSize (Value.Value.Buffer);
- NewValue.Buffer = AllocateCopyPool (NewValue.BufferLen, Value.Value.Buffer);
- if (NewValue.Buffer == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- goto RELEASE_RESOURCE;
- }
- break;
- default:
- ASSERT (FALSE);
- break;
- }
-
- Status = RedfishPlatformConfigSetStatementCommon (RedfishPlatformConfigPrivate, FullSchema, ConfigureLang, &NewValue);
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "%a, failed to set value to statement: %r\n", __FUNCTION__, Status));
- }
-
-RELEASE_RESOURCE:
-
- if (FullSchema != NULL) {
- FreePool (FullSchema);
- }
-
- return Status;
-}
-
-/**
- Get the list of Configure Language from platform configuration by the given Schema and Pattern.
-
- @param[in] This Pointer to EDKII_REDFISH_PLATFORM_CONFIG_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 ConfigureLangList.
-
- @retval EFI_SUCCESS ConfigureLangList is returned successfully.
- @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 *RedfishPlatformConfigPrivate;
- 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 == NULL || IS_EMPTY_STRING (Schema) || IS_EMPTY_STRING (Version) || Count == NULL || ConfigureLangList == NULL || IS_EMPTY_STRING (Pattern)) {
- return EFI_INVALID_PARAMETER;
- }
-
- *Count = 0;
- *ConfigureLangList = NULL;
- FullSchema = NULL;
- RedfishPlatformConfigPrivate = REDFISH_PLATFORM_CONFIG_PRIVATE_FROM_THIS (This);
-
- Status = ProcessPendingList (&RedfishPlatformConfigPrivate->FormsetList, &RedfishPlatformConfigPrivate->PendingList);
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "%a, ProcessPendingList failure: %r\n", __FUNCTION__, Status));
- return Status;
- }
-
- FullSchema = GetFullSchemaString (Schema, Version);
- if (FullSchema == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
-
- Status = GetStatementPrivateByConfigureLangRegex (
- RedfishPlatformConfigPrivate->RegularExpressionProtocol,
- &RedfishPlatformConfigPrivate->FormsetList,
- FullSchema,
- Pattern,
- &StatementList
- );
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "%a, GetStatementPrivateByConfigureLangRegex failure: %r\n", __FUNCTION__, Status));
- goto RELEASE_RESOURCE;
- }
-
- if (!IsListEmpty (&StatementList.StatementList)) {
-
- TmpConfigureLangList = AllocateZeroPool (sizeof (CHAR16 *) * StatementList.Count);
- if (TmpConfigureLangList == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- goto RELEASE_RESOURCE;
- }
-
- Index = 0;
- NextLink = GetFirstNode (&StatementList.StatementList);
- while (!IsNull (&StatementList.StatementList, NextLink)) {
- StatementRef = REDFISH_PLATFORM_CONFIG_STATEMENT_REF_FROM_LINK (NextLink);
- NextLink = GetNextNode (&StatementList.StatementList, NextLink);
-
- ASSERT (StatementRef->Statement->Description != 0);
- if (StatementRef->Statement->Description != 0) {
- TmpString = HiiGetRedfishString (StatementRef->Statement->ParentForm->ParentFormset->HiiHandle, FullSchema, StatementRef->Statement->Description);
- ASSERT (TmpString != NULL);
- if (TmpString != NULL) {
- TmpConfigureLangList[Index] = AllocateCopyPool (StrSize (TmpString), TmpString);
- ASSERT (TmpConfigureLangList[Index] != NULL);
- FreePool (TmpString);
- ++Index;
- }
- }
- }
- }
-
- *Count = StatementList.Count;
- *ConfigureLangList = TmpConfigureLangList;
-
-RELEASE_RESOURCE:
-
- if (FullSchema != 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_CONFIG_PROTOCOL instance.
- @param[in] HiiHandle The target handle to search. If handle is NULL,
- this function return all schema from HII database.
- @param[out] SupportedSchema The supported schema list which is separated by ';'.
- The SupportedSchema is allocated by the callee. It's caller's
- responsibility to free this buffer using 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 == NULL || SupportedSchema == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- *SupportedSchema = NULL;
-
- RedfishPlatformConfigPrivate = REDFISH_PLATFORM_CONFIG_PRIVATE_FROM_THIS (This);
-
- Status = ProcessPendingList (&RedfishPlatformConfigPrivate->FormsetList, &RedfishPlatformConfigPrivate->PendingList);
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "%a, ProcessPendingList failure: %r\n", __FUNCTION__, Status));
- return Status;
- }
-
- if (IsListEmpty (&RedfishPlatformConfigPrivate->FormsetList)) {
- return EFI_NOT_FOUND;
- }
-
- //
- // Calculate for string buffer size.
- //
- StringSize = 0;
- HiiFormsetLink = GetFirstNode (&RedfishPlatformConfigPrivate->FormsetList);
- while (!IsNull (&RedfishPlatformConfigPrivate->FormsetList, HiiFormsetLink)) {
- HiiFormsetNextLink = GetNextNode (&RedfishPlatformConfigPrivate->FormsetList, HiiFormsetLink);
- HiiFormsetPrivate = REDFISH_PLATFORM_CONFIG_FORMSET_FROM_LINK (HiiFormsetLink);
-
- if (HiiHandle != NULL && HiiHandle != HiiFormsetPrivate->HiiHandle) {
- HiiFormsetLink = HiiFormsetNextLink;
- continue;
- }
-
- if (HiiFormsetPrivate->SupportedSchema.Count > 0) {
- for (Index = 0; Index < HiiFormsetPrivate->SupportedSchema.Count; Index++) {
- StringSize += AsciiStrSize (HiiFormsetPrivate->SupportedSchema.SchemaList[Index]);
- }
- }
-
- HiiFormsetLink = HiiFormsetNextLink;
- }
-
- if (StringSize == 0) {
- return EFI_NOT_FOUND;
- }
-
- StringBuffer = AllocatePool (StringSize);
- if (StringBuffer == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
-
- StringIndex = 0;
- HiiFormsetLink = GetFirstNode (&RedfishPlatformConfigPrivate->FormsetList);
- while (!IsNull (&RedfishPlatformConfigPrivate->FormsetList, HiiFormsetLink)) {
- HiiFormsetNextLink = GetNextNode (&RedfishPlatformConfigPrivate->FormsetList, HiiFormsetLink);
- HiiFormsetPrivate = REDFISH_PLATFORM_CONFIG_FORMSET_FROM_LINK (HiiFormsetLink);
-
- if (HiiHandle != NULL && HiiHandle != HiiFormsetPrivate->HiiHandle) {
- HiiFormsetLink = HiiFormsetNextLink;
- continue;
- }
-
- if (HiiFormsetPrivate->SupportedSchema.Count > 0) {
- for (Index = 0; Index < HiiFormsetPrivate->SupportedSchema.Count; Index++) {
- AsciiStrCpyS (&StringBuffer[StringIndex], (StringSize - StringIndex), HiiFormsetPrivate->SupportedSchema.SchemaList[Index]);
- StringIndex += AsciiStrLen (HiiFormsetPrivate->SupportedSchema.SchemaList[Index]);
- StringBuffer[StringIndex] = ';';
- ++StringIndex;
- }
- }
-
- HiiFormsetLink = HiiFormsetNextLink;
- }
-
- StringBuffer[--StringIndex] = '\0';
-
- *SupportedSchema = 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 == EFI_HII_DATABASE_NOTIFY_NEW_PACK || NotifyType == EFI_HII_DATABASE_NOTIFY_ADD_PACK) {
- //
- // HII formset on this handle is updated by driver during run-time. The formset needs to be reloaded.
- //
- Status = NotifyFormsetUpdate (Handle, &mRedfishPlatformConfigPrivate->PendingList);
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "%a, failed to notify updated formset of HII handle: 0x%x\n", __FUNCTION__, Handle));
- return Status;
- }
- } else if (NotifyType == EFI_HII_DATABASE_NOTIFY_REMOVE_PACK) {
- //
- // HII resource is removed. The formset is no longer exist.
- //
- Status = NotifyFormsetDeleted (Handle, &mRedfishPlatformConfigPrivate->PendingList);
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "%a, failed to notify deleted formset of HII handle: 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 = 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 = 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 = 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 = mRedfishPlatformConfigPrivate->HiiDatabase->RegisterPackageNotify (
- mRedfishPlatformConfigPrivate->HiiDatabase,
- EFI_HII_PACKAGE_FORMS,
- NULL,
- RedfishPlatformConfigFormUpdateNotify,
- EFI_HII_DATABASE_NOTIFY_NEW_PACK,
- &mRedfishPlatformConfigPrivate->NotifyHandle
- );
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "%a, RegisterPackageNotify for EFI_HII_DATABASE_NOTIFY_NEW_PACK failure: %r\n", __FUNCTION__, Status));
- }
-
- //
- // Register package notification when new form package is updated.
- //
- Status = mRedfishPlatformConfigPrivate->HiiDatabase->RegisterPackageNotify (
- mRedfishPlatformConfigPrivate->HiiDatabase,
- EFI_HII_PACKAGE_FORMS,
- NULL,
- RedfishPlatformConfigFormUpdateNotify,
- EFI_HII_DATABASE_NOTIFY_ADD_PACK,
- &mRedfishPlatformConfigPrivate->NotifyHandle
- );
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "%a, RegisterPackageNotify for EFI_HII_DATABASE_NOTIFY_NEW_PACK failure: %r\n", __FUNCTION__, Status));
- }
-
-#if REDFISH_PLATFORM_CONFIG_DELETE_EXPIRED_FORMSET
- //
- // Register package notification when new form package is removed.
- //
- Status = mRedfishPlatformConfigPrivate->HiiDatabase->RegisterPackageNotify (
- mRedfishPlatformConfigPrivate->HiiDatabase,
- EFI_HII_PACKAGE_FORMS,
- NULL,
- RedfishPlatformConfigFormUpdateNotify,
- EFI_HII_DATABASE_NOTIFY_REMOVE_PACK,
- &mRedfishPlatformConfigPrivate->NotifyHandle
- );
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "%a, RegisterPackageNotify for EFI_HII_DATABASE_NOTIFY_NEW_PACK failure: %r\n", __FUNCTION__, Status));
- }
-#endif
-
- gBS->CloseEvent (Event);
- mRedfishPlatformConfigPrivate->HiiDbNotify.ProtocolEvent = 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 = gBS->LocateProtocol (
- &gEfiRegularExpressionProtocolGuid,
- NULL,
- (VOID **)&mRedfishPlatformConfigPrivate->RegularExpressionProtocol
- );
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "%a, locate EFI_REGULAR_EXPRESSION_PROTOCOL failure: %r\n", __FUNCTION__, Status));
- return;
- }
-
- gBS->CloseEvent (Event);
- mRedfishPlatformConfigPrivate->RegexNotify.ProtocolEvent = NULL;
-
-}
-
-/**
- Unloads an image.
-
- @param ImageHandle Handle that identifies the image to be unloaded.
-
- @retval EFI_SUCCESS The image has been unloaded.
- @retval EFI_INVALID_PARAMETER ImageHandle is not a valid image handle.
-
-**/
-EFI_STATUS
-EFIAPI
-RedfishPlatformConfigDxeUnload (
- IN EFI_HANDLE ImageHandle
- )
-{
- EFI_STATUS Status;
-
- if (mRedfishPlatformConfigPrivate != NULL) {
- Status = gBS->UninstallProtocolInterface (
- mRedfishPlatformConfigPrivate->ImageHandle,
- &gEdkIIRedfishPlatformConfigProtocolGuid,
- (VOID*)&mRedfishPlatformConfigPrivate->Protocol
- );
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "%a, can not uninstall gEdkIIRedfishPlatformConfigProtocolGuid: %r\n", __FUNCTION__, Status));
- ASSERT (FALSE);
- }
-
- //
- // Close events
- //
- if (mRedfishPlatformConfigPrivate->HiiDbNotify.ProtocolEvent != NULL) {
- gBS->CloseEvent (mRedfishPlatformConfigPrivate->HiiDbNotify.ProtocolEvent);
- }
- if (mRedfishPlatformConfigPrivate->HiiStringNotify.ProtocolEvent != NULL) {
- gBS->CloseEvent (mRedfishPlatformConfigPrivate->HiiStringNotify.ProtocolEvent);
- }
- if (mRedfishPlatformConfigPrivate->RegexNotify.ProtocolEvent != NULL) {
- gBS->CloseEvent (mRedfishPlatformConfigPrivate->RegexNotify.ProtocolEvent);
- }
-
- //
- // Unregister package notification.
- //
- if (mRedfishPlatformConfigPrivate->NotifyHandle != NULL) {
- mRedfishPlatformConfigPrivate->HiiDatabase->UnregisterPackageNotify (
- mRedfishPlatformConfigPrivate->HiiDatabase,
- mRedfishPlatformConfigPrivate->NotifyHandle
- );
- }
-
- ReleaseFormsetList (&mRedfishPlatformConfigPrivate->FormsetList);
- FreePool (mRedfishPlatformConfigPrivate);
- mRedfishPlatformConfigPrivate = 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 including
- 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 = (REDFISH_PLATFORM_CONFIG_PRIVATE *)AllocateZeroPool (sizeof (REDFISH_PLATFORM_CONFIG_PRIVATE));
- if (mRedfishPlatformConfigPrivate == NULL) {
- DEBUG ((DEBUG_ERROR, "%a, can not allocate pool for REDFISH_PLATFORM_CONFIG_PRIVATE\n", __FUNCTION__));
- ASSERT (FALSE);
- return EFI_OUT_OF_RESOURCES;
- }
-
- //
- // Protocol initialization
- //
- mRedfishPlatformConfigPrivate->ImageHandle = ImageHandle;
- mRedfishPlatformConfigPrivate->Protocol.GetValue = RedfishPlatformConfigProtocolGetValue;
- mRedfishPlatformConfigPrivate->Protocol.SetValue = RedfishPlatformConfigProtocolSetValue;
- mRedfishPlatformConfigPrivate->Protocol.GetConfigureLang = RedfishPlatformConfigProtocolGetConfigureLang;
- mRedfishPlatformConfigPrivate->Protocol.GetSupportedSchema = RedfishPlatformConfigProtocolGetSupportedSchema;
-
- InitializeListHead (&mRedfishPlatformConfigPrivate->FormsetList);
- InitializeListHead (&mRedfishPlatformConfigPrivate->PendingList);
-
- Status = gBS->InstallProtocolInterface (
- &ImageHandle,
- &gEdkIIRedfishPlatformConfigProtocolGuid,
- EFI_NATIVE_INTERFACE,
- (VOID*)&mRedfishPlatformConfigPrivate->Protocol
- );
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "%a, can not install gEdkIIRedfishPlatformConfigProtocolGuid: %r\n", __FUNCTION__, Status));
- ASSERT (FALSE);
- }
-
- //
- // Install protocol notification if HII database protocol is installed.
- //
- mRedfishPlatformConfigPrivate->HiiDbNotify.ProtocolEvent = EfiCreateProtocolNotifyEvent (
- &gEfiHiiDatabaseProtocolGuid,
- TPL_CALLBACK,
- HiiDatabaseProtocolInstalled,
- NULL,
- &mRedfishPlatformConfigPrivate->HiiDbNotify.Registration
- );
- if (mRedfishPlatformConfigPrivate->HiiDbNotify.ProtocolEvent == NULL) {
- DEBUG ((DEBUG_ERROR, "%a, failed to create protocol notification for gEfiHiiDatabaseProtocolGuid\n", __FUNCTION__));
- ASSERT (FALSE);
- }
-
- //
- // Install protocol notification if HII string protocol is installed.
- //
- mRedfishPlatformConfigPrivate->HiiStringNotify.ProtocolEvent = EfiCreateProtocolNotifyEvent (
- &gEfiHiiStringProtocolGuid,
- TPL_CALLBACK,
- HiiStringProtocolInstalled,
- NULL,
- &mRedfishPlatformConfigPrivate->HiiStringNotify.Registration
- );
- if (mRedfishPlatformConfigPrivate->HiiStringNotify.ProtocolEvent == NULL) {
- DEBUG ((DEBUG_ERROR, "%a, failed to create protocol notification for gEfiHiiStringProtocolGuid\n", __FUNCTION__));
- ASSERT (FALSE);
- }
-
- //
- // Install protocol notification if regular expression protocol is installed.
- //
- mRedfishPlatformConfigPrivate->RegexNotify.ProtocolEvent = EfiCreateProtocolNotifyEvent (
- &gEfiRegularExpressionProtocolGuid,
- TPL_CALLBACK,
- RegexProtocolInstalled,
- NULL,
- &mRedfishPlatformConfigPrivate->RegexNotify.Registration
- );
- if (mRedfishPlatformConfigPrivate->RegexNotify.ProtocolEvent == NULL) {
- DEBUG ((DEBUG_ERROR, "%a, failed to create protocol notification for gEfiRegularExpressionProtocolGuid\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<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "RedfishPlatformConfigDxe.h"
+#include "RedfishPlatformConfigImpl.h"
+
+REDFISH_PLATFORM_CONFIG_PRIVATE *mRedfishPlatformConfigPrivate = 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 = 0;
+ switch (Value->Type) {
+ case EFI_IFR_TYPE_NUM_SIZE_8:
+ Temp = Value->Value.u8;
+ break;
+
+ case EFI_IFR_TYPE_NUM_SIZE_16:
+ Temp = Value->Value.u16;
+ break;
+
+ case EFI_IFR_TYPE_NUM_SIZE_32:
+ Temp = Value->Value.u32;
+ break;
+
+ case EFI_IFR_TYPE_BOOLEAN:
+ Temp = 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 buffer.
+
+ @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 != NULL);
+
+ switch (Type) {
+ case EFI_IFR_TYPE_NUM_SIZE_8:
+ *(((UINT8 *) Array) + Index) = (UINT8) Value;
+ break;
+
+ case EFI_IFR_TYPE_NUM_SIZE_16:
+ *(((UINT16 *) Array) + Index) = (UINT16) Value;
+ break;
+
+ case EFI_IFR_TYPE_NUM_SIZE_32:
+ *(((UINT32 *) Array) + Index) = (UINT32) Value;
+ break;
+
+ case EFI_IFR_TYPE_NUM_SIZE_64:
+ *(((UINT64 *) Array) + Index) = (UINT64) Value;
+ break;
+
+ default:
+ break;
+ }
+}
+
+/**
+ Return data element in an Array by its Index in ordered list array buffer.
+
+ @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 != NULL);
+
+ Data = 0;
+ switch (Type) {
+ case EFI_IFR_TYPE_NUM_SIZE_8:
+ Data = (UINT64) *(((UINT8 *) Array) + Index);
+ break;
+
+ case EFI_IFR_TYPE_NUM_SIZE_16:
+ Data = (UINT64) *(((UINT16 *) Array) + Index);
+ break;
+
+ case EFI_IFR_TYPE_NUM_SIZE_32:
+ Data = (UINT64) *(((UINT32 *) Array) + Index);
+ break;
+
+ case EFI_IFR_TYPE_NUM_SIZE_64:
+ Data = (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 == NULL) {
+ return 0;
+ }
+
+ if (HiiStatement->Operand != EFI_IFR_ORDERED_LIST_OP) {
+ return 0;
+ }
+
+ if (IsListEmpty (&HiiStatement->OptionListHead)) {
+ return 0;
+ }
+
+ Found = FALSE;
+ Link = GetFirstNode (&HiiStatement->OptionListHead);
+ while (!IsNull (&HiiStatement->OptionListHead, Link)) {
+ Option = HII_QUESTION_OPTION_FROM_LINK (Link);
+
+ CurrentValue = ExtendHiiValueToU64 (&Option->Value);
+ if (Value == CurrentValue) {
+ return Option->Text;
+ }
+
+ Link = 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 second value.
+ -1 is returned when second value is greater than first value.
+
+**/
+INTN
+CompareHiiStatementValue (
+ IN HII_STATEMENT_VALUE *Value1,
+ IN HII_STATEMENT_VALUE *Value2
+ )
+{
+ INTN Result;
+ UINT64 Data1;
+ UINT64 Data2;
+
+ if (Value1 == NULL || Value2 == NULL) {
+ return -1;
+ }
+
+ switch (Value1->Type) {
+ case EFI_IFR_TYPE_NUM_SIZE_8:
+ Data1 = Value1->Value.u8;
+ break;
+ case EFI_IFR_TYPE_NUM_SIZE_16:
+ Data1 = Value1->Value.u16;
+ break;
+ case EFI_IFR_TYPE_NUM_SIZE_32:
+ Data1 = Value1->Value.u32;
+ break;
+ case EFI_IFR_TYPE_NUM_SIZE_64:
+ Data1 = Value1->Value.u64;
+ break;
+ case EFI_IFR_TYPE_BOOLEAN:
+ Data1 = (Value1->Value.b ? 1 : 0);
+ break;
+ default:
+ return -1;
+ }
+
+ switch (Value2->Type) {
+ case EFI_IFR_TYPE_NUM_SIZE_8:
+ Data2 = Value2->Value.u8;
+ break;
+ case EFI_IFR_TYPE_NUM_SIZE_16:
+ Data2 = Value2->Value.u16;
+ break;
+ case EFI_IFR_TYPE_NUM_SIZE_32:
+ Data2 = Value2->Value.u32;
+ break;
+ case EFI_IFR_TYPE_NUM_SIZE_64:
+ Data2 = Value2->Value.u64;
+ break;
+ case EFI_IFR_TYPE_BOOLEAN:
+ Data2 = (Value2->Value.b ? 1 : 0);
+ break;
+ default:
+ return -1;
+ }
+
+ Result = (Data1 == 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 != EFI_IFR_ONE_OF_OP) {
+ return 0;
+ }
+
+ if (IsListEmpty (&Statement->HiiStatement->OptionListHead)) {
+ return 0;
+ }
+
+ Link = GetFirstNode (&Statement->HiiStatement->OptionListHead);
+ while (!IsNull (&Statement->HiiStatement->OptionListHead, Link)) {
+ Option = HII_QUESTION_OPTION_FROM_LINK (Link);
+
+ if (CompareHiiStatementValue (&Statement->HiiStatement->Value, &Option->Value) == 0) {
+ return Option->Text;
+ }
+
+ Link = 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 == NULL || IS_EMPTY_STRING (HiiString) || Value == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (Statement->HiiStatement->Operand != EFI_IFR_ONE_OF_OP) {
+ return EFI_UNSUPPORTED;
+ }
+
+ if (IsListEmpty (&Statement->HiiStatement->OptionListHead)) {
+ return EFI_NOT_FOUND;
+ }
+
+ Found = FALSE;
+ Link = GetFirstNode (&Statement->HiiStatement->OptionListHead);
+ while (!IsNull (&Statement->HiiStatement->OptionListHead, Link)) {
+ Option = HII_QUESTION_OPTION_FROM_LINK (Link);
+
+ TmpString = HiiGetRedfishString (Statement->ParentForm->ParentFormset->HiiHandle, Schema, Option->Text);
+ if (TmpString != NULL) {
+ if (StrCmp (TmpString, HiiString) == 0) {
+ CopyMem (Value, &Option->Value, sizeof (HII_STATEMENT_VALUE));
+ Found = TRUE;
+ }
+ FreePool (TmpString);
+ }
+
+ if (Found) {
+ return EFI_SUCCESS;
+ }
+
+ Link = 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 == NULL || RedfishValue == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ switch (Value->Type) {
+ case EFI_IFR_TYPE_NUM_SIZE_8:
+ RedfishValue->Type = REDFISH_VALUE_TYPE_INTEGER;
+ RedfishValue->Value.Integer = (INT64)Value->Value.u8;
+ break;
+ case EFI_IFR_TYPE_NUM_SIZE_16:
+ RedfishValue->Type = REDFISH_VALUE_TYPE_INTEGER;
+ RedfishValue->Value.Integer = (INT64)Value->Value.u16;
+ break;
+ case EFI_IFR_TYPE_NUM_SIZE_32:
+ RedfishValue->Type = REDFISH_VALUE_TYPE_INTEGER;
+ RedfishValue->Value.Integer = (INT64)Value->Value.u32;
+ break;
+ case EFI_IFR_TYPE_NUM_SIZE_64:
+ RedfishValue->Type = REDFISH_VALUE_TYPE_INTEGER;
+ RedfishValue->Value.Integer = (INT64)Value->Value.u64;
+ break;
+ case EFI_IFR_TYPE_BOOLEAN:
+ RedfishValue->Type = REDFISH_VALUE_TYPE_BOOLEAN;
+ RedfishValue->Value.Boolean = Value->Value.b;
+ break;
+ default:
+ RedfishValue->Type = 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 == NULL || RedfishValue == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ switch (RedfishValue->Type) {
+ case REDFISH_VALUE_TYPE_INTEGER:
+ Value->Type = EFI_IFR_TYPE_NUM_SIZE_64;
+ Value->Value.u64 = (UINT64)RedfishValue->Value.Integer;
+ break;
+ case REDFISH_VALUE_TYPE_BOOLEAN:
+ Value->Type = EFI_IFR_TYPE_BOOLEAN;
+ Value->Value.b = RedfishValue->Value.Boolean;
+ break;
+ default:
+ Value->Type = 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 == NULL || OrderedListStatement->Operand != EFI_IFR_ORDERED_LIST_OP) {
+ return;
+ }
+
+ DEBUG ((DEBUG_ERROR, "Value.Type= 0x%x\n", OrderedListStatement->Value.Type));
+ DEBUG ((DEBUG_ERROR, "Value.BufferValueType= 0x%x\n", OrderedListStatement->Value.BufferValueType));
+ DEBUG ((DEBUG_ERROR, "Value.BufferLen= 0x%x\n", OrderedListStatement->Value.BufferLen));
+ DEBUG ((DEBUG_ERROR, "Value.Buffer= 0x%x\n", OrderedListStatement->Value.Buffer));
+ DEBUG ((DEBUG_ERROR, "Value.MaxContainers= 0x%x\n", OrderedListStatement->ExtraData.OrderListData.MaxContainers));
+ DEBUG ((DEBUG_ERROR, "StorageWidth= 0x%x\n", OrderedListStatement->StorageWidth));
+
+ if (OrderedListStatement->Value.Buffer == NULL) {
+ return;
+ }
+
+ Value8 = NULL;
+ Value16 = NULL;
+ Value32 = NULL;
+ Value64 = NULL;
+ Count = 0;
+
+ switch (OrderedListStatement->Value.BufferValueType) {
+ case EFI_IFR_TYPE_NUM_SIZE_8:
+ Value8 = (UINT8 *)OrderedListStatement->Value.Buffer;
+ Count = OrderedListStatement->StorageWidth / sizeof (UINT8);
+ for (Index = 0; Index < Count; Index++) {
+ DEBUG ((DEBUG_ERROR, "%d ", Value8[Index]));
+ }
+ break;
+ case EFI_IFR_TYPE_NUM_SIZE_16:
+ Value16 = (UINT16 *)OrderedListStatement->Value.Buffer;
+ Count = OrderedListStatement->StorageWidth / sizeof (UINT16);
+ for (Index = 0; Index < Count; Index++) {
+ DEBUG ((DEBUG_ERROR, "%d ", Value16[Index]));
+ }
+ break;
+ case EFI_IFR_TYPE_NUM_SIZE_32:
+ Value32 = (UINT32 *)OrderedListStatement->Value.Buffer;
+ Count = OrderedListStatement->StorageWidth / sizeof (UINT32);
+ for (Index = 0; Index < Count; Index++) {
+ DEBUG ((DEBUG_ERROR, "%d ", Value32[Index]));
+ }
+ break;
+ case EFI_IFR_TYPE_NUM_SIZE_64:
+ Value64 = (UINT64 *)OrderedListStatement->Value.Buffer;
+ Count = OrderedListStatement->StorageWidth / sizeof (UINT64);
+ for (Index = 0; Index < Count; Index++) {
+ DEBUG ((DEBUG_ERROR, "%d ", Value64[Index]));
+ }
+ break;
+ default:
+ Value8 = (UINT8 *)OrderedListStatement->Value.Buffer;
+ Count = OrderedListStatement->StorageWidth / sizeof (UINT8);
+ for (Index = 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 list.
+
+**/
+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 == NULL || ReturnSize == NULL) {
+ return NULL;
+ }
+
+ *ReturnSize = 0;
+
+ if (Statement->HiiStatement->Operand != EFI_IFR_ORDERED_LIST_OP) {
+ return NULL;
+ }
+
+ if (IsListEmpty (&Statement->HiiStatement->OptionListHead)) {
+ return NULL;
+ }
+
+ DEBUG_CODE (
+ DumpOrderedListValue (Statement->HiiStatement);
+ );
+
+ OptionCount = 0;
+ Link = GetFirstNode (&Statement->HiiStatement->OptionListHead);
+ while (!IsNull (&Statement->HiiStatement->OptionListHead, Link)) {
+ Option = HII_QUESTION_OPTION_FROM_LINK (Link);
+
+ ++OptionCount;
+
+ Link = GetNextNode (&Statement->HiiStatement->OptionListHead, Link);
+ }
+
+ *ReturnSize = OptionCount;
+ ReturnedArray = AllocatePool (sizeof (EFI_STRING_ID) * OptionCount);
+ if (ReturnedArray == NULL) {
+ DEBUG ((DEBUG_ERROR, "%a, out of resource\n", __FUNCTION__));
+ *ReturnSize = 0;
+ return NULL;
+ }
+
+ for (Index = 0; Index < OptionCount; Index++) {
+ Value = OrderedListGetArrayData (Statement->HiiStatement->Value.Buffer, Statement->HiiStatement->Value.BufferValueType, Index);
+ ReturnedArray[Index] = 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 == NULL || IS_EMPTY_STRING (HiiString) || Value == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ *Value = 0;
+
+ if (Statement->HiiStatement->Operand != EFI_IFR_ORDERED_LIST_OP) {
+ return EFI_UNSUPPORTED;
+ }
+
+ if (IsListEmpty (&Statement->HiiStatement->OptionListHead)) {
+ return EFI_NOT_FOUND;
+ }
+
+ Found = FALSE;
+ Link = GetFirstNode (&Statement->HiiStatement->OptionListHead);
+ while (!IsNull (&Statement->HiiStatement->OptionListHead, Link)) {
+ Option = HII_QUESTION_OPTION_FROM_LINK (Link);
+
+ TmpString = HiiGetRedfishString (Statement->ParentForm->ParentFormset->HiiHandle, Schema, Option->Text);
+ if (TmpString != NULL) {
+ if (StrCmp (TmpString, HiiString) == 0) {
+ *Value = ExtendHiiValueToU64 (&Option->Value);
+ Found = TRUE;
+ }
+ FreePool (TmpString);
+ }
+
+ if (Found) {
+ return EFI_SUCCESS;
+ }
+
+ Link = 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 == NULL || AsciiString[0] == '\0') {
+ return NULL;
+ }
+
+ StringLen = AsciiStrLen (AsciiString) + 1;
+ Buffer = AllocatePool (StringLen * sizeof (CHAR16));
+ if (Buffer == NULL) {
+ return NULL;
+ }
+
+ Status = 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 = AsciiStrSize(CONFIGURE_LANGUAGE_PREFIX) + AsciiStrSize (Schema) + AsciiStrSize (Version);
+
+ FullName = AllocatePool (Size);
+ if (FullName == NULL) {
+ DEBUG ((DEBUG_ERROR, "%a, out-of-resource\n", __FUNCTION__));
+ return NULL;
+ }
+
+ AsciiSPrint (FullName, Size, "%a%a.%a", CONFIGURE_LANGUAGE_PREFIX, Schema, 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 refers 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 *RedfishPlatformConfigPrivate,
+ 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 == NULL || IS_EMPTY_STRING (Schema) || IS_EMPTY_STRING (ConfigureLang) || Statement == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ *Statement = NULL;
+
+ Status = ProcessPendingList (&RedfishPlatformConfigPrivate->FormsetList, &RedfishPlatformConfigPrivate->PendingList);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a, ProcessPendingList failure: %r\n", __FUNCTION__, Status));
+ return Status;
+ }
+
+ TargetStatement = GetStatementPrivateByConfigureLang (&RedfishPlatformConfigPrivate->FormsetList, Schema, ConfigureLang);
+ if (TargetStatement == 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 = 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 == EFI_IFR_TYPE_UNDEFINED) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ //
+ // Return Value.
+ //
+ *Statement = TargetStatement;
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Get Redfish value with the given Schema and Configure Language.
+
+ @param[in] This Pointer to EDKII_REDFISH_PLATFORM_CONFIG_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 configure 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 == NULL || IS_EMPTY_STRING (Schema) || IS_EMPTY_STRING (Version) || IS_EMPTY_STRING (ConfigureLang) || Value == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ RedfishPlatformConfigPrivate = REDFISH_PLATFORM_CONFIG_PRIVATE_FROM_THIS (This);
+ Value->Type = REDFISH_VALUE_TYPE_UNKNOWN;
+ Value->ArrayCount = 0;
+ Count = 0;
+ FullSchema = NULL;
+ HiiString = NULL;
+ StringIdArray = NULL;
+
+ FullSchema = GetFullSchemaString (Schema, Version);
+ if (FullSchema == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ Status = RedfishPlatformConfigGetStatementCommon (RedfishPlatformConfigPrivate, FullSchema, ConfigureLang, &TargetStatement);
+ if (EFI_ERROR (Status)) {
+ goto RELEASE_RESOURCE;
+ }
+
+ switch (TargetStatement->HiiStatement->Operand) {
+ case EFI_IFR_ONE_OF_OP:
+ StringId = HiiValueToOneOfOptionStringId (TargetStatement);
+ if (StringId == 0) {
+ ASSERT (FALSE);
+ Status = EFI_DEVICE_ERROR;
+ goto RELEASE_RESOURCE;
+ }
+
+ Value->Value.Buffer = HiiGetRedfishAsciiString (TargetStatement->ParentForm->ParentFormset->HiiHandle, FullSchema, StringId);
+ if (Value->Value.Buffer == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto RELEASE_RESOURCE;
+ }
+
+ Value->Type = REDFISH_VALUE_TYPE_STRING;
+ break;
+ case EFI_IFR_STRING_OP:
+ if (TargetStatement->HiiStatement->Value.Type != EFI_IFR_TYPE_STRING) {
+ ASSERT (FALSE);
+ Status = EFI_DEVICE_ERROR;
+ goto RELEASE_RESOURCE;
+ }
+
+ Value->Type = REDFISH_VALUE_TYPE_STRING;
+ Value->Value.Buffer = AllocatePool (StrLen ((CHAR16 *)TargetStatement->HiiStatement->Value.Buffer) + 1);
+ UnicodeStrToAsciiStrS ((CHAR16 *)TargetStatement->HiiStatement->Value.Buffer, Value->Value.Buffer, StrLen ((CHAR16 *)TargetStatement->HiiStatement->Value.Buffer) + 1);
+ break;
+ case EFI_IFR_CHECKBOX_OP:
+ case EFI_IFR_NUMERIC_OP:
+ Status = HiiValueToRedfishNumeric (&TargetStatement->HiiStatement->Value, Value);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a, failed to convert HII value to Redfish value: %r\n", __FUNCTION__, Status));
+ goto RELEASE_RESOURCE;
+ }
+ break;
+ case EFI_IFR_ACTION_OP:
+ if (TargetStatement->HiiStatement->Value.Type != EFI_IFR_TYPE_ACTION) {
+ ASSERT (FALSE);
+ Status = EFI_DEVICE_ERROR;
+ goto RELEASE_RESOURCE;
+ }
+
+ //
+ // Action has no value. Just return unknown type.
+ //
+ Value->Type = REDFISH_VALUE_TYPE_UNKNOWN;
+ break;
+ case EFI_IFR_ORDERED_LIST_OP:
+ StringIdArray = HiiValueToOrderedListOptionStringId (TargetStatement, &Count);
+ if (StringIdArray == NULL) {
+ ASSERT (FALSE);
+ Status = EFI_DEVICE_ERROR;
+ goto RELEASE_RESOURCE;
+ }
+
+ Value->Value.StringArray = AllocatePool (sizeof (CHAR8 *) * Count);
+ if (Value->Value.StringArray == NULL) {
+ ASSERT (FALSE);
+ Status = EFI_OUT_OF_RESOURCES;
+ goto RELEASE_RESOURCE;
+ }
+
+ for (Index = 0; Index < Count; Index++) {
+ ASSERT (StringIdArray[Index] != 0);
+ Value->Value.StringArray[Index] = HiiGetRedfishAsciiString (TargetStatement->ParentForm->ParentFormset->HiiHandle, FullSchema, StringIdArray[Index]);
+ }
+
+ Value->ArrayCount = Count;
+ Value->Type = REDFISH_VALUE_TYPE_STRING_ARRAY;
+ break;
+ default:
+ DEBUG ((DEBUG_ERROR, "%a, catch unsupported type: 0x%x! Please contact with author if we need to support this type.\n", __FUNCTION__, TargetStatement->HiiStatement->Operand));
+ ASSERT (FALSE);
+ Status = EFI_UNSUPPORTED;
+ goto RELEASE_RESOURCE;
+ }
+
+RELEASE_RESOURCE:
+
+ if (FullSchema != NULL) {
+ FreePool (FullSchema);
+ }
+
+ if (HiiString != NULL) {
+ FreePool (HiiString);
+ }
+
+ if (StringIdArray != 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 == NULL || HiiForm == NULL || HiiStatement == NULL || Value == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Status = SetQuestionValue (
+ HiiFormset,
+ HiiForm,
+ HiiStatement,
+ Value
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a, failed to set question value: %r\n", __FUNCTION__, Status));
+ return Status;
+ }
+
+ Status = 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 refers 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 == NULL || IS_EMPTY_STRING (Schema) || IS_EMPTY_STRING (ConfigureLang) || StatementValue == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ TempBuffer = NULL;
+ StringArray = NULL;
+
+ Status = ProcessPendingList (&RedfishPlatformConfigPrivate->FormsetList, &RedfishPlatformConfigPrivate->PendingList);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a, ProcessPendingList failure: %r\n", __FUNCTION__, Status));
+ return Status;
+ }
+
+ TargetStatement = GetStatementPrivateByConfigureLang (&RedfishPlatformConfigPrivate->FormsetList, Schema, ConfigureLang);
+ if (TargetStatement == 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 != 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 == EFI_IFR_ONE_OF_OP && StatementValue->Type == EFI_IFR_TYPE_STRING) {
+
+ TempBuffer = StrToUnicodeStr ((CHAR8 *)StatementValue->Buffer);
+ if (TempBuffer == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ FreePool (StatementValue->Buffer);
+ StatementValue->Buffer = NULL;
+ StatementValue->BufferLen = 0;
+
+ Status = HiiStringToOneOfOptionValue (TargetStatement, Schema, TempBuffer, 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 == EFI_IFR_ORDERED_LIST_OP && StatementValue->Type == 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 = AllocateZeroPool (TargetStatement->HiiStatement->StorageWidth);
+ if (StringArray == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ //
+ // Arrage new option order from input string array
+ //
+ CharArray = (CHAR8 **)StatementValue->Buffer;
+ for (Index = 0; Index < StatementValue->BufferLen; Index++) {
+ TempBuffer = StrToUnicodeStr (CharArray[Index]);
+ if (TempBuffer == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ Status = HiiStringToOrderedListOptionValue (TargetStatement, Schema, TempBuffer, &Value);
+ if (EFI_ERROR (Status)) {
+ ASSERT (FALSE);
+ continue;
+ }
+ FreePool (TempBuffer);
+ OrderedListSetArrayData (StringArray, TargetStatement->HiiStatement->Value.BufferValueType, Index, Value);
+ }
+
+ StatementValue->Type = EFI_IFR_TYPE_BUFFER;
+ StatementValue->Buffer = StringArray;
+ StatementValue->BufferLen = TargetStatement->HiiStatement->StorageWidth;
+ StatementValue->BufferValueType = TargetStatement->HiiStatement->Value.BufferValueType;
+ } else if (TargetStatement->HiiStatement->Operand == EFI_IFR_NUMERIC_OP && StatementValue->Type == EFI_IFR_TYPE_NUM_SIZE_64) {
+ //
+ // Redfish only has numeric value type and it does not care about the value size.
+ // Do a patch here so we have proper value size applied.
+ //
+ StatementValue->Type = 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, TargetStatement->HiiStatement->Value.Type));
+ ASSERT (FALSE);
+ }
+ }
+
+ Status = 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", __FUNCTION__, Status));
+ return Status;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Set Redfish value with the given Schema and Configure Language.
+
+ @param[in] This Pointer to EDKII_REDFISH_PLATFORM_CONFIG_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 configure 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 == NULL || IS_EMPTY_STRING (Schema) || IS_EMPTY_STRING (Version) || IS_EMPTY_STRING (ConfigureLang)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (Value.Type == REDFISH_VALUE_TYPE_UNKNOWN || Value.Type >= REDFISH_VALUE_TYPE_MAX) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ RedfishPlatformConfigPrivate = REDFISH_PLATFORM_CONFIG_PRIVATE_FROM_THIS (This);
+ FullSchema = NULL;
+
+ FullSchema = GetFullSchemaString (Schema, Version);
+ if (FullSchema == 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 = RedfishNumericToHiiValue (&Value, &NewValue);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a, failed to convert Redfish value to Hii value: %r\n", __FUNCTION__, Status));
+ goto RELEASE_RESOURCE;
+ }
+ break;
+ case REDFISH_VALUE_TYPE_STRING:
+ NewValue.Type = EFI_IFR_TYPE_STRING;
+ NewValue.BufferLen = (UINT16)AsciiStrSize (Value.Value.Buffer);
+ NewValue.Buffer = AllocateCopyPool (NewValue.BufferLen, Value.Value.Buffer);
+ if (NewValue.Buffer == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto RELEASE_RESOURCE;
+ }
+ break;
+ case REDFISH_VALUE_TYPE_STRING_ARRAY:
+ NewValue.Type = EFI_IFR_TYPE_STRING;
+ NewValue.BufferLen = (UINT16)Value.ArrayCount;
+ NewValue.Buffer = (UINT8 *)Value.Value.StringArray;
+ break;
+ default:
+ ASSERT (FALSE);
+ break;
+ }
+
+ Status = RedfishPlatformConfigSetStatementCommon (RedfishPlatformConfigPrivate, FullSchema, ConfigureLang, &NewValue);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a, failed to set value to statement: %r\n", __FUNCTION__, Status));
+ }
+
+RELEASE_RESOURCE:
+
+ if (FullSchema != NULL) {
+ FreePool (FullSchema);
+ }
+
+ return Status;
+}
+
+/**
+ Get the list of Configure Language from platform configuration by the given Schema and RegexPattern.
+
+ @param[in] This Pointer to EDKII_REDFISH_PLATFORM_CONFIG_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 ConfigureLangList.
+
+ @retval EFI_SUCCESS ConfigureLangList is returned successfully.
+ @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 *RedfishPlatformConfigPrivate;
+ 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 == NULL || IS_EMPTY_STRING (Schema) || IS_EMPTY_STRING (Version) || Count == NULL || ConfigureLangList == NULL || IS_EMPTY_STRING (RegexPattern)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ *Count = 0;
+ *ConfigureLangList = NULL;
+ FullSchema = NULL;
+ RedfishPlatformConfigPrivate = REDFISH_PLATFORM_CONFIG_PRIVATE_FROM_THIS (This);
+
+ Status = ProcessPendingList (&RedfishPlatformConfigPrivate->FormsetList, &RedfishPlatformConfigPrivate->PendingList);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a, ProcessPendingList failure: %r\n", __FUNCTION__, Status));
+ return Status;
+ }
+
+ FullSchema = GetFullSchemaString (Schema, Version);
+ if (FullSchema == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ Status = GetStatementPrivateByConfigureLangRegex (
+ RedfishPlatformConfigPrivate->RegularExpressionProtocol,
+ &RedfishPlatformConfigPrivate->FormsetList,
+ FullSchema,
+ RegexPattern,
+ &StatementList
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a, GetStatementPrivateByConfigureLangRegex failure: %r\n", __FUNCTION__, Status));
+ goto RELEASE_RESOURCE;
+ }
+
+ if (!IsListEmpty (&StatementList.StatementList)) {
+
+ TmpConfigureLangList = AllocateZeroPool (sizeof (CHAR16 *) * StatementList.Count);
+ if (TmpConfigureLangList == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto RELEASE_RESOURCE;
+ }
+
+ Index = 0;
+ NextLink = GetFirstNode (&StatementList.StatementList);
+ while (!IsNull (&StatementList.StatementList, NextLink)) {
+ StatementRef = REDFISH_PLATFORM_CONFIG_STATEMENT_REF_FROM_LINK (NextLink);
+ NextLink = GetNextNode (&StatementList.StatementList, NextLink);
+
+ ASSERT (StatementRef->Statement->Description != 0);
+ if (StatementRef->Statement->Description != 0) {
+ TmpString = HiiGetRedfishString (StatementRef->Statement->ParentForm->ParentFormset->HiiHandle, FullSchema, StatementRef->Statement->Description);
+ ASSERT (TmpString != NULL);
+ if (TmpString != NULL) {
+ TmpConfigureLangList[Index] = AllocateCopyPool (StrSize (TmpString), TmpString);
+ ASSERT (TmpConfigureLangList[Index] != NULL);
+ FreePool (TmpString);
+ ++Index;
+ }
+ }
+ }
+ }
+
+ *Count = StatementList.Count;
+ *ConfigureLangList = TmpConfigureLangList;
+
+RELEASE_RESOURCE:
+
+ if (FullSchema != 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_CONFIG_PROTOCOL instance.
+ @param[in] HiiHandle The target handle to search. If handle is NULL,
+ this function return all schema from HII database.
+ @param[out] SupportedSchema The supported schema list which is separated by ';'.
+ The SupportedSchema is allocated by the callee. It's caller's
+ responsibility to free this buffer using 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 == NULL || SupportedSchema == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ *SupportedSchema = NULL;
+
+ RedfishPlatformConfigPrivate = REDFISH_PLATFORM_CONFIG_PRIVATE_FROM_THIS (This);
+
+ Status = ProcessPendingList (&RedfishPlatformConfigPrivate->FormsetList, &RedfishPlatformConfigPrivate->PendingList);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a, ProcessPendingList failure: %r\n", __FUNCTION__, Status));
+ return Status;
+ }
+
+ if (IsListEmpty (&RedfishPlatformConfigPrivate->FormsetList)) {
+ return EFI_NOT_FOUND;
+ }
+
+ //
+ // Calculate for string buffer size.
+ //
+ StringSize = 0;
+ HiiFormsetLink = GetFirstNode (&RedfishPlatformConfigPrivate->FormsetList);
+ while (!IsNull (&RedfishPlatformConfigPrivate->FormsetList, HiiFormsetLink)) {
+ HiiFormsetNextLink = GetNextNode (&RedfishPlatformConfigPrivate->FormsetList, HiiFormsetLink);
+ HiiFormsetPrivate = REDFISH_PLATFORM_CONFIG_FORMSET_FROM_LINK (HiiFormsetLink);
+
+ if (HiiHandle != NULL && HiiHandle != HiiFormsetPrivate->HiiHandle) {
+ HiiFormsetLink = HiiFormsetNextLink;
+ continue;
+ }
+
+ if (HiiFormsetPrivate->SupportedSchema.Count > 0) {
+ for (Index = 0; Index < HiiFormsetPrivate->SupportedSchema.Count; Index++) {
+ StringSize += AsciiStrSize (HiiFormsetPrivate->SupportedSchema.SchemaList[Index]);
+ }
+ }
+
+ HiiFormsetLink = HiiFormsetNextLink;
+ }
+
+ if (StringSize == 0) {
+ return EFI_NOT_FOUND;
+ }
+
+ StringBuffer = AllocatePool (StringSize);
+ if (StringBuffer == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ StringIndex = 0;
+ HiiFormsetLink = GetFirstNode (&RedfishPlatformConfigPrivate->FormsetList);
+ while (!IsNull (&RedfishPlatformConfigPrivate->FormsetList, HiiFormsetLink)) {
+ HiiFormsetNextLink = GetNextNode (&RedfishPlatformConfigPrivate->FormsetList, HiiFormsetLink);
+ HiiFormsetPrivate = REDFISH_PLATFORM_CONFIG_FORMSET_FROM_LINK (HiiFormsetLink);
+
+ if (HiiHandle != NULL && HiiHandle != HiiFormsetPrivate->HiiHandle) {
+ HiiFormsetLink = HiiFormsetNextLink;
+ continue;
+ }
+
+ if (HiiFormsetPrivate->SupportedSchema.Count > 0) {
+ for (Index = 0; Index < HiiFormsetPrivate->SupportedSchema.Count; Index++) {
+ AsciiStrCpyS (&StringBuffer[StringIndex], (StringSize - StringIndex), HiiFormsetPrivate->SupportedSchema.SchemaList[Index]);
+ StringIndex += AsciiStrLen (HiiFormsetPrivate->SupportedSchema.SchemaList[Index]);
+ StringBuffer[StringIndex] = ';';
+ ++StringIndex;
+ }
+ }
+
+ HiiFormsetLink = HiiFormsetNextLink;
+ }
+
+ StringBuffer[--StringIndex] = '\0';
+
+ *SupportedSchema = 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 == EFI_HII_DATABASE_NOTIFY_NEW_PACK || NotifyType == EFI_HII_DATABASE_NOTIFY_ADD_PACK) {
+ //
+ // HII formset on this handle is updated by driver during run-time. The formset needs to be reloaded.
+ //
+ Status = NotifyFormsetUpdate (Handle, &mRedfishPlatformConfigPrivate->PendingList);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a, failed to notify updated formset of HII handle: 0x%x\n", __FUNCTION__, Handle));
+ return Status;
+ }
+ } else if (NotifyType == EFI_HII_DATABASE_NOTIFY_REMOVE_PACK) {
+ //
+ // HII resource is removed. The formset is no longer exist.
+ //
+ Status = NotifyFormsetDeleted (Handle, &mRedfishPlatformConfigPrivate->PendingList);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a, failed to notify deleted formset of HII handle: 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 = 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 = 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 = 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 = mRedfishPlatformConfigPrivate->HiiDatabase->RegisterPackageNotify (
+ mRedfishPlatformConfigPrivate->HiiDatabase,
+ EFI_HII_PACKAGE_FORMS,
+ NULL,
+ RedfishPlatformConfigFormUpdateNotify,
+ EFI_HII_DATABASE_NOTIFY_NEW_PACK,
+ &mRedfishPlatformConfigPrivate->NotifyHandle
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a, RegisterPackageNotify for EFI_HII_DATABASE_NOTIFY_NEW_PACK failure: %r\n", __FUNCTION__, Status));
+ }
+
+ //
+ // Register package notification when new form package is updated.
+ //
+ Status = mRedfishPlatformConfigPrivate->HiiDatabase->RegisterPackageNotify (
+ mRedfishPlatformConfigPrivate->HiiDatabase,
+ EFI_HII_PACKAGE_FORMS,
+ NULL,
+ RedfishPlatformConfigFormUpdateNotify,
+ EFI_HII_DATABASE_NOTIFY_ADD_PACK,
+ &mRedfishPlatformConfigPrivate->NotifyHandle
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a, RegisterPackageNotify for EFI_HII_DATABASE_NOTIFY_NEW_PACK failure: %r\n", __FUNCTION__, Status));
+ }
+
+ gBS->CloseEvent (Event);
+ mRedfishPlatformConfigPrivate->HiiDbNotify.ProtocolEvent = 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 = gBS->LocateProtocol (
+ &gEfiRegularExpressionProtocolGuid,
+ NULL,
+ (VOID **)&mRedfishPlatformConfigPrivate->RegularExpressionProtocol
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a, locate EFI_REGULAR_EXPRESSION_PROTOCOL failure: %r\n", __FUNCTION__, Status));
+ return;
+ }
+
+ gBS->CloseEvent (Event);
+ mRedfishPlatformConfigPrivate->RegexNotify.ProtocolEvent = NULL;
+
+}
+
+/**
+ Unloads an image.
+
+ @param ImageHandle Handle that identifies the image to be unloaded.
+
+ @retval EFI_SUCCESS The image has been unloaded.
+ @retval EFI_INVALID_PARAMETER ImageHandle is not a valid image handle.
+
+**/
+EFI_STATUS
+EFIAPI
+RedfishPlatformConfigDxeUnload (
+ IN EFI_HANDLE ImageHandle
+ )
+{
+ EFI_STATUS Status;
+
+ if (mRedfishPlatformConfigPrivate != NULL) {
+ Status = gBS->UninstallProtocolInterface (
+ mRedfishPlatformConfigPrivate->ImageHandle,
+ &gEdkIIRedfishPlatformConfigProtocolGuid,
+ (VOID*)&mRedfishPlatformConfigPrivate->Protocol
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a, can not uninstall gEdkIIRedfishPlatformConfigProtocolGuid: %r\n", __FUNCTION__, Status));
+ ASSERT (FALSE);
+ }
+
+ //
+ // Close events
+ //
+ if (mRedfishPlatformConfigPrivate->HiiDbNotify.ProtocolEvent != NULL) {
+ gBS->CloseEvent (mRedfishPlatformConfigPrivate->HiiDbNotify.ProtocolEvent);
+ }
+ if (mRedfishPlatformConfigPrivate->HiiStringNotify.ProtocolEvent != NULL) {
+ gBS->CloseEvent (mRedfishPlatformConfigPrivate->HiiStringNotify.ProtocolEvent);
+ }
+ if (mRedfishPlatformConfigPrivate->RegexNotify.ProtocolEvent != NULL) {
+ gBS->CloseEvent (mRedfishPlatformConfigPrivate->RegexNotify.ProtocolEvent);
+ }
+
+ //
+ // Unregister package notification.
+ //
+ if (mRedfishPlatformConfigPrivate->NotifyHandle != NULL) {
+ mRedfishPlatformConfigPrivate->HiiDatabase->UnregisterPackageNotify (
+ mRedfishPlatformConfigPrivate->HiiDatabase,
+ mRedfishPlatformConfigPrivate->NotifyHandle
+ );
+ }
+
+ ReleaseFormsetList (&mRedfishPlatformConfigPrivate->FormsetList);
+ FreePool (mRedfishPlatformConfigPrivate);
+ mRedfishPlatformConfigPrivate = 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 including
+ 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 = (REDFISH_PLATFORM_CONFIG_PRIVATE *)AllocateZeroPool (sizeof (REDFISH_PLATFORM_CONFIG_PRIVATE));
+ if (mRedfishPlatformConfigPrivate == NULL) {
+ DEBUG ((DEBUG_ERROR, "%a, can not allocate pool for REDFISH_PLATFORM_CONFIG_PRIVATE\n", __FUNCTION__));
+ ASSERT (FALSE);
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ //
+ // Protocol initialization
+ //
+ mRedfishPlatformConfigPrivate->ImageHandle = ImageHandle;
+ mRedfishPlatformConfigPrivate->Protocol.GetValue = RedfishPlatformConfigProtocolGetValue;
+ mRedfishPlatformConfigPrivate->Protocol.SetValue = RedfishPlatformConfigProtocolSetValue;
+ mRedfishPlatformConfigPrivate->Protocol.GetConfigureLang = RedfishPlatformConfigProtocolGetConfigureLang;
+ mRedfishPlatformConfigPrivate->Protocol.GetSupportedSchema = RedfishPlatformConfigProtocolGetSupportedSchema;
+
+ InitializeListHead (&mRedfishPlatformConfigPrivate->FormsetList);
+ InitializeListHead (&mRedfishPlatformConfigPrivate->PendingList);
+
+ Status = gBS->InstallProtocolInterface (
+ &ImageHandle,
+ &gEdkIIRedfishPlatformConfigProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ (VOID*)&mRedfishPlatformConfigPrivate->Protocol
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a, can not install gEdkIIRedfishPlatformConfigProtocolGuid: %r\n", __FUNCTION__, Status));
+ ASSERT (FALSE);
+ }
+
+ //
+ // Install protocol notification if HII database protocol is installed.
+ //
+ mRedfishPlatformConfigPrivate->HiiDbNotify.ProtocolEvent = EfiCreateProtocolNotifyEvent (
+ &gEfiHiiDatabaseProtocolGuid,
+ TPL_CALLBACK,
+ HiiDatabaseProtocolInstalled,
+ NULL,
+ &mRedfishPlatformConfigPrivate->HiiDbNotify.Registration
+ );
+ if (mRedfishPlatformConfigPrivate->HiiDbNotify.ProtocolEvent == NULL) {
+ DEBUG ((DEBUG_ERROR, "%a, failed to create protocol notification for gEfiHiiDatabaseProtocolGuid\n", __FUNCTION__));
+ ASSERT (FALSE);
+ }
+
+ //
+ // Install protocol notification if HII string protocol is installed.
+ //
+ mRedfishPlatformConfigPrivate->HiiStringNotify.ProtocolEvent = EfiCreateProtocolNotifyEvent (
+ &gEfiHiiStringProtocolGuid,
+ TPL_CALLBACK,
+ HiiStringProtocolInstalled,
+ NULL,
+ &mRedfishPlatformConfigPrivate->HiiStringNotify.Registration
+ );
+ if (mRedfishPlatformConfigPrivate->HiiStringNotify.ProtocolEvent == NULL) {
+ DEBUG ((DEBUG_ERROR, "%a, failed to create protocol notification for gEfiHiiStringProtocolGuid\n", __FUNCTION__));
+ ASSERT (FALSE);
+ }
+
+ //
+ // Install protocol notification if regular expression protocol is installed.
+ //
+ mRedfishPlatformConfigPrivate->RegexNotify.ProtocolEvent = EfiCreateProtocolNotifyEvent (
+ &gEfiRegularExpressionProtocolGuid,
+ TPL_CALLBACK,
+ RegexProtocolInstalled,
+ NULL,
+ &mRedfishPlatformConfigPrivate->RegexNotify.Registration
+ );
+ if (mRedfishPlatformConfigPrivate->RegexNotify.ProtocolEvent == NULL) {
+ DEBUG ((DEBUG_ERROR, "%a, failed to create protocol notification for gEfiRegularExpressionProtocolGuid\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<BR>
-
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#ifndef EDKII_REDFISH_PLATFORM_CONFIG_DXE_H_
-#define EDKII_REDFISH_PLATFORM_CONFIG_DXE_H_
-
-#include <Uefi.h>
-
-//
-// Libraries
-//
-#include <Library/BaseLib.h>
-#include <Library/BaseMemoryLib.h>
-#include <Library/DebugLib.h>
-#include <Library/MemoryAllocationLib.h>
-#include <Library/PrintLib.h>
-#include <Library/UefiLib.h>
-#include <Library/UefiBootServicesTableLib.h>
-#include <Library/UefiDriverEntryPoint.h>
-
-//
-// Produced Protocols
-//
-#include <Protocol/EdkIIRedfishPlatformConfig.h>
-#include <Protocol/HiiDatabase.h>
-#include <Protocol/HiiString.h>
-#include <Protocol/RegularExpressionProtocol.h>
-
-//
-// Definition of EDKII_REDFISH_PLATFORM_CONFIG_NOTIFY.
-//
-typedef struct {
- EFI_EVENT ProtocolEvent; // Protocol notification event.
- VOID *Registration; // Protocol notification registration.
-} 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<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef EDKII_REDFISH_PLATFORM_CONFIG_DXE_H_
+#define EDKII_REDFISH_PLATFORM_CONFIG_DXE_H_
+
+#include <Uefi.h>
+
+//
+// Libraries
+//
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PrintLib.h>
+#include <Library/UefiLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiDriverEntryPoint.h>
+
+//
+// Produced Protocols
+//
+#include <Protocol/EdkIIRedfishPlatformConfig.h>
+#include <Protocol/HiiDatabase.h>
+#include <Protocol/HiiString.h>
+#include <Protocol/RegularExpressionProtocol.h>
+
+//
+// Definition of EDKII_REDFISH_PLATFORM_CONFIG_NOTIFY.
+//
+typedef struct {
+ EFI_EVENT ProtocolEvent; // Protocol notification event.
+ VOID *Registration; // Protocol notification registration.
+} 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.inf 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<BR>
-# SPDX-License-Identifier: BSD-2-Clause-Patent
-#
-##
-
-[Defines]
- INF_VERSION = 0x00010005
- BASE_NAME = RedfishPlatformConfigDxe
- FILE_GUID = BEAEFFE1-0633-41B5-913C-9389339C2927
- MODULE_TYPE = DXE_DRIVER
- VERSION_STRING = 1.0
- ENTRY_POINT = RedfishPlatformConfigDxeEntryPoint
- UNLOAD_IMAGE = 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<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = RedfishPlatformConfigDxe
+ FILE_GUID = BEAEFFE1-0633-41B5-913C-9389339C2927
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ ENTRY_POINT = RedfishPlatformConfigDxeEntryPoint
+ UNLOAD_IMAGE = 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..917f946656 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<BR>
-
- 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 == NULL || StringId == 0) {
- DEBUG ((DEBUG_INFO, "???"));
- return EFI_INVALID_PARAMETER;
- }
-
- String = HiiGetString (HiiHandle, StringId, NULL);
- if (String == 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 == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- Index = 0;
- HiiFormLink = GetFirstNode (&FormsetPrivate->HiiFormList);
- while (!IsNull (&FormsetPrivate->HiiFormList, HiiFormLink)) {
- HiiFormPrivate = REDFISH_PLATFORM_CONFIG_FORM_FROM_LINK (HiiFormLink);
- HiiNextFormLink = GetNextNode (&FormsetPrivate->HiiFormList, HiiFormLink);
-
- DEBUG ((DEBUG_INFO, " [%d] form: %d title: ", ++Index, HiiFormPrivate->Id));
- DumpHiiString (FormsetPrivate->HiiHandle, HiiFormPrivate->Title);
- DEBUG ((DEBUG_INFO, "\n"));
-
- HiiStatementLink = GetFirstNode (&HiiFormPrivate->StatementList);
- while (!IsNull (&HiiFormPrivate->StatementList, HiiStatementLink)) {
- HiiStatementPrivate = REDFISH_PLATFORM_CONFIG_STATEMENT_FROM_LINK (HiiStatementLink);
- HiiNextStatementLink = GetNextNode (&HiiFormPrivate->StatementList, HiiStatementLink);
-
- DEBUG ((DEBUG_INFO, " QID: 0x%x Prompt: ", HiiStatementPrivate->QuestionId));
- DumpHiiString (FormsetPrivate->HiiHandle, HiiStatementPrivate->Description);
- DEBUG ((DEBUG_INFO, "\n"));
-
- HiiStatementLink = HiiNextStatementLink;
- }
-
- HiiFormLink = 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 == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- if (IsListEmpty (FormsetList)) {
- DEBUG ((DEBUG_INFO, "%a, Empty formset list\n", __FUNCTION__));
- return EFI_SUCCESS;
- }
-
- Index = 0;
- HiiFormsetLink = GetFirstNode (FormsetList);
- while (!IsNull (FormsetList, HiiFormsetLink)) {
- HiiFormsetNextLink = GetNextNode (FormsetList, HiiFormsetLink);
- HiiFormsetPrivate = REDFISH_PLATFORM_CONFIG_FORMSET_FROM_LINK (HiiFormsetLink);
-
- DEBUG ((DEBUG_INFO, "[%d] HII Handle: 0x%x formset: %g at %s\n", ++Index, HiiFormsetPrivate->HiiHandle, &HiiFormsetPrivate->Guid, HiiFormsetPrivate->DevicePathStr));
- DumpFormset (HiiFormsetPrivate);
-
- HiiFormsetLink = 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 responsible
- 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 string 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 == NULL || HiiHandle == NULL || StringId == 0 || IS_EMPTY_STRING (Language)) {
- ASSERT (FALSE);
- return NULL;
- }
-
- //
- // Retrieve the size of the string in the string package for the BestLanguage
- //
- StringSize = 0;
- Status = 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 GetString()
- // returns an error other than EFI_BUFFER_TOO_SMALL, then HiiHandle is not present
- // in the HII Database
- //
- if (Status != EFI_BUFFER_TOO_SMALL) {
- return NULL;
- }
-
- //
- // Allocate a buffer for the return string
- //
- String = AllocateZeroPool (StringSize);
- if (String == NULL) {
- return NULL;
- }
-
- //
- // Retrieve the string from the string package
- //
- Status = 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 = 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 string 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 otherwise.
-
-**/
-BOOLEAN
-CheckSupportedSchema (
- IN REDFISH_PLATFORM_CONFIG_SCHEMA *SupportedSchema,
- IN CHAR8 *Schema
- )
-{
- UINTN Index;
-
- if (SupportedSchema == NULL || IS_EMPTY_STRING (Schema)) {
- return FALSE;
- }
-
- if (SupportedSchema->Count == 0) {
- return FALSE;
- }
-
- for (Index = 0; Index < SupportedSchema->Count; Index++) {
- if (AsciiStrCmp (SupportedSchema->SchemaList[Index], Schema) == 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 NULL.
- @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 == NULL || SupportedSchema == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- SupportedSchema->Count = 0;
-
- SupportedLanguages = HiiGetSupportedLanguages (HiiHandle);
- if (SupportedLanguages == NULL) {
- return EFI_NOT_FOUND;
- }
-
- Index = 0;
- LangIndex = 0;
- Count = 0;
- while (TRUE) {
- if (SupportedLanguages[Index] == ';' || SupportedLanguages[Index] == '\0') {
- if (AsciiStrnCmp (&SupportedLanguages[LangIndex], X_UEFI_SCHEMA_PREFIX, AsciiStrLen (X_UEFI_SCHEMA_PREFIX)) == 0) {
- ++Count;
- }
- LangIndex = Index + 1;
- }
-
- if (SupportedLanguages[Index] == '\0') {
- break;
- }
-
- ++Index;
- }
-
- if (Count == 0) {
- return EFI_NOT_FOUND;
- }
-
- SupportedSchema->Count = Count;
- SupportedSchema->SchemaList = AllocatePool (sizeof (CHAR8 *) * Count);
- if (SupportedSchema->SchemaList == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
-
- Index = 0;
- LangIndex = 0;
- ListIndex = 0;
- while (TRUE) {
-
- if (SupportedLanguages[Index] == ';' || SupportedLanguages[Index] == '\0') {
- if (AsciiStrnCmp (&SupportedLanguages[LangIndex], X_UEFI_SCHEMA_PREFIX, AsciiStrLen (X_UEFI_SCHEMA_PREFIX)) == 0) {
- StrSize = Index - LangIndex;
- SupportedSchema->SchemaList[ListIndex] = AllocateCopyPool ((StrSize + 1), &SupportedLanguages[LangIndex]);
- SupportedSchema->SchemaList[ListIndex][StrSize] = '\0';
- ++ListIndex;
- }
-
- LangIndex = Index + 1;
- }
-
- if (SupportedLanguages[Index] == '\0') {
- break;
- }
-
- ++Index;
- }
-
- return EFI_SUCCESS;
-}
-
-/**
- Search and find statement private instance by given regular expression patthern
- 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 *RegularExpressionProtocol,
- 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 == NULL || IS_EMPTY_STRING (Schema) || IS_EMPTY_STRING (Pattern) || StatementList == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- if (RegularExpressionProtocol == NULL) {
- return EFI_NOT_READY;
- }
-
- StatementList->Count = 0;
- InitializeListHead (&StatementList->StatementList);
-
- if (IsListEmpty (FormsetList)) {
- return EFI_NOT_FOUND;
- }
-
- HiiFormsetLink = GetFirstNode (FormsetList);
- while (!IsNull (FormsetList, HiiFormsetLink)) {
- HiiFormsetNextLink = GetNextNode (FormsetList, HiiFormsetLink);
- HiiFormsetPrivate = REDFISH_PLATFORM_CONFIG_FORMSET_FROM_LINK (HiiFormsetLink);
-
- //
- // Performance check.
- // If there is no desired Redfish schema found, skip this formset.
- //
- if (!CheckSupportedSchema (&HiiFormsetPrivate->SupportedSchema, Schema)) {
- HiiFormsetLink = HiiFormsetNextLink;
- continue;
- }
-
- HiiFormLink = GetFirstNode (&HiiFormsetPrivate->HiiFormList);
- while (!IsNull (&HiiFormsetPrivate->HiiFormList, HiiFormLink)) {
- HiiNextFormLink = GetNextNode (&HiiFormsetPrivate->HiiFormList, HiiFormLink);
- HiiFormPrivate = REDFISH_PLATFORM_CONFIG_FORM_FROM_LINK (HiiFormLink);
-
- HiiStatementLink =GetFirstNode (&HiiFormPrivate->StatementList);
- while (!IsNull (&HiiFormPrivate->StatementList, HiiStatementLink)) {
- HiiNextStatementLink = GetNextNode (&HiiFormPrivate->StatementList, HiiStatementLink);
- HiiStatementPrivate = REDFISH_PLATFORM_CONFIG_STATEMENT_FROM_LINK (HiiStatementLink);
-
- if (HiiStatementPrivate->Description != 0) {
- TmpString = HiiGetRedfishString (HiiFormsetPrivate->HiiHandle, Schema, HiiStatementPrivate->Description);
- if (TmpString != NULL) {
- Status = RegularExpressionProtocol->MatchString (
- RegularExpressionProtocol,
- TmpString,
- Pattern,
- &gEfiRegexSyntaxTypePerlGuid,
- &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 = AllocateZeroPool (sizeof (REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_REF));
- if (StatementRef == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
-
- StatementRef->Statement = HiiStatementPrivate;
- InsertTailList (&StatementList->StatementList, &StatementRef->Link);
- ++StatementList->Count;
- }
-
- FreePool (TmpString);
- }
- }
-
- HiiStatementLink = HiiNextStatementLink;
- }
-
- HiiFormLink = HiiNextFormLink;
- }
-
- HiiFormsetLink = 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 statement 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 == NULL || IS_EMPTY_STRING (Schema) || IS_EMPTY_STRING (ConfigureLang)) {
- return NULL;
- }
-
- if (IsListEmpty (FormsetList)) {
- return NULL;
- }
-
- HiiFormsetLink = GetFirstNode (FormsetList);
- while (!IsNull (FormsetList, HiiFormsetLink)) {
- HiiFormsetNextLink = GetNextNode (FormsetList, HiiFormsetLink);
- HiiFormsetPrivate = REDFISH_PLATFORM_CONFIG_FORMSET_FROM_LINK (HiiFormsetLink);
-
- //
- // Performance check.
- // If there is no desired Redfish schema found, skip this formset.
- //
- if (!CheckSupportedSchema (&HiiFormsetPrivate->SupportedSchema, Schema)) {
- HiiFormsetLink = HiiFormsetNextLink;
- continue;
- }
-
- HiiFormLink = GetFirstNode (&HiiFormsetPrivate->HiiFormList);
- while (!IsNull (&HiiFormsetPrivate->HiiFormList, HiiFormLink)) {
- HiiNextFormLink = GetNextNode (&HiiFormsetPrivate->HiiFormList, HiiFormLink);
- HiiFormPrivate = REDFISH_PLATFORM_CONFIG_FORM_FROM_LINK (HiiFormLink);
-
- HiiStatementLink =GetFirstNode (&HiiFormPrivate->StatementList);
- while (!IsNull (&HiiFormPrivate->StatementList, HiiStatementLink)) {
- HiiNextStatementLink = GetNextNode (&HiiFormPrivate->StatementList, HiiStatementLink);
- HiiStatementPrivate = REDFISH_PLATFORM_CONFIG_STATEMENT_FROM_LINK (HiiStatementLink);
-
- DEBUG_CODE (
- STATIC UINTN Index = 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 != 0) {
- TmpString = HiiGetRedfishString (HiiFormsetPrivate->HiiHandle, Schema, HiiStatementPrivate->Description);
- if (TmpString != NULL) {
- if (StrCmp (TmpString, ConfigureLang) == 0) {
- FreePool (TmpString);
- return HiiStatementPrivate;
- }
-
- FreePool (TmpString);
- }
- }
-
- HiiStatementLink = HiiNextStatementLink;
- }
-
- HiiFormLink = HiiNextFormLink;
- }
-
- HiiFormsetLink = 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 == NULL || FormsetList == NULL) {
- return NULL;
- }
-
- if (IsListEmpty (FormsetList)) {
- return NULL;
- }
-
- HiiFormsetLink = GetFirstNode (FormsetList);
- while (!IsNull (FormsetList, HiiFormsetLink)) {
- HiiFormsetNextLink = GetNextNode (FormsetList, HiiFormsetLink);
- HiiFormsetPrivate = REDFISH_PLATFORM_CONFIG_FORMSET_FROM_LINK (HiiFormsetLink);
-
- if (HiiFormsetPrivate->HiiHandle == HiiHandle) {
- return HiiFormsetPrivate;
- }
-
- HiiFormsetLink = HiiFormsetNextLink;
- }
-
- return NULL;
-}
-
-/**
- Release formset and all the forms and statements that belong to this formset.
-
- @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 == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- HiiFormLink = GetFirstNode (&FormsetPrivate->HiiFormList);
- while (!IsNull (&FormsetPrivate->HiiFormList, HiiFormLink)) {
- HiiFormPrivate = REDFISH_PLATFORM_CONFIG_FORM_FROM_LINK (HiiFormLink);
- HiiNextFormLink = GetNextNode (&FormsetPrivate->HiiFormList, HiiFormLink);
-
- HiiStatementLink = GetFirstNode (&HiiFormPrivate->StatementList);
- while (!IsNull (&HiiFormPrivate->StatementList, HiiStatementLink)) {
- HiiStatementPrivate = REDFISH_PLATFORM_CONFIG_STATEMENT_FROM_LINK (HiiStatementLink);
- HiiNextStatementLink = GetNextNode (&HiiFormPrivate->StatementList, HiiStatementLink);
-
- //
- // HiiStatementPrivate->HiiStatement will be released in DestroyFormSet().
- //
-
- if (HiiStatementPrivate->DesStringCache != NULL) {
- FreePool (HiiStatementPrivate->DesStringCache);
- HiiStatementPrivate->DesStringCache = NULL;
- }
-
- RemoveEntryList (&HiiStatementPrivate->Link);
- FreePool (HiiStatementPrivate);
- HiiStatementLink = HiiNextStatementLink;
- }
-
- //
- // HiiStatementPrivate->HiiForm will be released in DestroyFormSet().
- //
-
- RemoveEntryList (&HiiFormPrivate->Link);
- FreePool (HiiFormPrivate);
- HiiFormLink = HiiNextFormLink;
- }
-
- if (FormsetPrivate->HiiFormSet != NULL) {
- DestroyFormSet (FormsetPrivate->HiiFormSet);
- FormsetPrivate->HiiFormSet = NULL;
- }
-
- FreePool (FormsetPrivate->DevicePathStr);
-
- //
- // Release schema list
- //
- if (FormsetPrivate->SupportedSchema.SchemaList != NULL) {
- for (Index = 0; Index < FormsetPrivate->SupportedSchema.Count; Index++) {
- FreePool (FormsetPrivate->SupportedSchema.SchemaList[Index]);
- }
-
- FreePool (FormsetPrivate->SupportedSchema.SchemaList);
- FormsetPrivate->SupportedSchema.SchemaList = NULL;
- FormsetPrivate->SupportedSchema.Count = 0;
- }
-
- return EFI_SUCCESS;
-}
-
-/**
- Create new form-set instance.
-
- @retval REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE * Pointer to newly created form-set private instance.
-
-**/
-REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *
-NewFormsetPrivate (
- VOID
- )
-{
- REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *NewFormsetPrivate;
-
- NewFormsetPrivate = AllocateZeroPool (sizeof (REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE));
- if (NewFormsetPrivate == 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 == NULL || FormsetPrivate == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
-
- HiiFormSet = AllocateZeroPool (sizeof (HII_FORMSET));
- if (HiiFormSet == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
-
- //
- // Find HII formset by the given HII handle.
- //
- ZeroMem (&ZeroGuid, sizeof (ZeroGuid));
- Status = CreateFormSetFromHiiHandle (HiiHandle, &ZeroGuid, HiiFormSet);
- if (EFI_ERROR (Status) || IsListEmpty (&HiiFormSet->FormListHead)) {
- Status = EFI_NOT_FOUND;
- goto ErrorExit;
- }
-
- //
- // Initialize formset
- //
- InitializeFormSet (HiiFormSet);
-
- //
- // Initialize formset private data.
- //
- FormsetPrivate->HiiFormSet = HiiFormSet;
- FormsetPrivate->HiiHandle = HiiHandle;
- CopyGuid (&FormsetPrivate->Guid, &HiiFormSet->Guid);
- FormsetPrivate->DevicePathStr = ConvertDevicePathToText (HiiFormSet->DevicePath, FALSE, FALSE);
- Status = GetSupportedSchema (FormsetPrivate->HiiHandle, &FormsetPrivate->SupportedSchema);
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_WARN, "%a, No schema from HII handle: 0x%x found: %r\n", __FUNCTION__, FormsetPrivate->HiiHandle, Status));
- }
-
- HiiFormLink = GetFirstNode (&HiiFormSet->FormListHead);
- while (!IsNull (&HiiFormSet->FormListHead, HiiFormLink)) {
- HiiForm = HII_FORM_FROM_LINK (HiiFormLink);
-
- HiiFormPrivate = AllocateZeroPool (sizeof (REDFISH_PLATFORM_CONFIG_FORM_PRIVATE));
- if (HiiFormPrivate == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- goto ErrorExit;
- }
-
- //
- // Initialize form private data.
- //
- HiiFormPrivate->HiiForm = HiiForm;
- HiiFormPrivate->Id = HiiForm->FormId;
- HiiFormPrivate->Title = HiiForm->FormTitle;
- HiiFormPrivate->ParentFormset = FormsetPrivate;
- InitializeListHead (&HiiFormPrivate->StatementList);
-
- HiiStatementLink = GetFirstNode (&HiiForm->StatementListHead);
- while (!IsNull (&HiiForm->StatementListHead, HiiStatementLink)) {
- HiiStatement = HII_STATEMENT_FROM_LINK (HiiStatementLink);
-
- HiiStatementPrivate = AllocateZeroPool (sizeof (REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE));
- if (HiiStatementPrivate == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- goto ErrorExit;
- }
- //
- // Initialize statement private data.
- //
- HiiStatementPrivate->HiiStatement = HiiStatement;
- HiiStatementPrivate->QuestionId = HiiStatement->QuestionId;
- HiiStatementPrivate->Description = HiiStatement->Prompt;
- HiiStatementPrivate->ParentForm = HiiFormPrivate;
-
- //
- // Attach to statement list.
- //
- InsertTailList (&HiiFormPrivate->StatementList, &HiiStatementPrivate->Link);
- HiiStatementLink = GetNextNode (&HiiForm->StatementListHead, HiiStatementLink);
- }
- //
- // Attach to form list.
- //
- InsertTailList (&FormsetPrivate->HiiFormList, &HiiFormPrivate->Link);
- HiiFormLink = GetNextNode (&HiiFormSet->FormListHead, HiiFormLink);
- }
-
- return EFI_SUCCESS;
-
-ErrorExit:
-
- //
- // Release HiiFormSet if HiiFormSet is not linked to FormsetPrivate yet.
- //
- if (HiiFormSet != NULL && FormsetPrivate->HiiFormSet != 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 == NULL || FormsetList == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- FormsetPrivate = GetFormsetPrivateByHiiHandle (HiiHandle, FormsetList);
- if (FormsetPrivate != NULL) {
- return EFI_ALREADY_STARTED;
- }
-
- FormsetPrivate = NewFormsetPrivate ();
- if (FormsetPrivate == NULL) {
- DEBUG ((DEBUG_ERROR, "%a, out of resource\n", __FUNCTION__));
- return EFI_OUT_OF_RESOURCES;
- }
-
- //
- // Load formset on the given HII handle.
- //
- Status = 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 == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- if (IsListEmpty (FormsetList)) {
- return EFI_SUCCESS;
- }
-
- HiiFormsetLink = GetFirstNode (FormsetList);
- while (!IsNull (FormsetList, HiiFormsetLink)) {
- HiiFormsetNextLink = GetNextNode (FormsetList, HiiFormsetLink);
- HiiFormsetPrivate = REDFISH_PLATFORM_CONFIG_FORMSET_FROM_LINK (HiiFormsetLink);
-
- //
- // Detach from list.
- //
- RemoveEntryList (&HiiFormsetPrivate->Link);
- ReleaseFormset (HiiFormsetPrivate);
- FreePool (HiiFormsetPrivate);
- HiiFormsetLink = 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 == NULL || PendingList == NULL) {
- return NULL;
- }
-
- if (IsListEmpty (PendingList)) {
- return NULL;
- }
-
- PendingListLink = GetFirstNode (PendingList);
- while (!IsNull (PendingList, PendingListLink)) {
- Target = REDFISH_PLATFORM_CONFIG_PENDING_LIST_FROM_LINK (PendingListLink);
-
- if (Target->HiiHandle == HiiHandle) {
- return Target;
- }
-
- PendingListLink = 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 recently 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 == NULL || PendingList == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- //
- // Check and see if this HII handle is processed already.
- //
- TargetPendingList = GetPendingList (HiiHandle, PendingList);
- if (TargetPendingList != NULL) {
- TargetPendingList->IsDeleted = FALSE;
- DEBUG_CODE (
- DEBUG ((DEBUG_INFO, "%a, HII handle: 0x%x is updated\n", __FUNCTION__, HiiHandle));
- );
- return EFI_SUCCESS;
- }
-
- TargetPendingList= AllocateZeroPool (sizeof (REDFISH_PLATFORM_CONFIG_PENDING_LIST));
- if (TargetPendingList == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
-
- TargetPendingList->HiiHandle = HiiHandle;
- TargetPendingList->IsDeleted = 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 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 recently 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 == NULL || PendingList == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- //
- // Check and see if this HII handle is processed already.
- //
- TargetPendingList = GetPendingList (HiiHandle, PendingList);
- if (TargetPendingList != NULL) {
- TargetPendingList->IsDeleted = TRUE;
- DEBUG_CODE (
- DEBUG ((DEBUG_INFO, "%a, HII handle: 0x%x is updated and deleted\n", __FUNCTION__, HiiHandle));
- );
- return EFI_SUCCESS;
- }
-
- TargetPendingList= AllocateZeroPool (sizeof (REDFISH_PLATFORM_CONFIG_PENDING_LIST));
- if (TargetPendingList == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
-
- TargetPendingList->HiiHandle = HiiHandle;
- TargetPendingList->IsDeleted = 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 NULL.
-
-**/
-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 == NULL || PendingList == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- if (IsListEmpty (PendingList)) {
- return EFI_SUCCESS;
- }
-
- PendingListLink = GetFirstNode (PendingList);
- while (!IsNull (PendingList, PendingListLink)) {
- PendingListNextLink = GetNextNode (PendingList, PendingListLink);
- Target = REDFISH_PLATFORM_CONFIG_PENDING_LIST_FROM_LINK (PendingListLink);
-
- if (Target->IsDeleted) {
- //
- // The HII resource on this HII handle is removed. Release the formset.
- //
- FormsetPrivate = GetFormsetPrivateByHiiHandle (Target->HiiHandle, FormsetList);
- if (FormsetPrivate != NULL) {
- DEBUG ((DEBUG_INFO, "%a, formset: %g is removed because driver release 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 already\n", __FUNCTION__, Target->HiiHandle));
- }
- } else {
- //
- // The HII resource on this HII handle is updated/removed.
- //
- FormsetPrivate = GetFormsetPrivateByHiiHandle (Target->HiiHandle, FormsetList);
- if (FormsetPrivate != NULL) {
- //
- // HII formset already exist, release it and query again.
- //
- DEBUG ((DEBUG_INFO, "%a, formset: %g is updated. Release current formset\n", __FUNCTION__, &FormsetPrivate->Guid));
- RemoveEntryList (&FormsetPrivate->Link);
- ReleaseFormset (FormsetPrivate);
- FreePool (FormsetPrivate);
- }
-
- Status = LoadFormsetList (Target->HiiHandle, FormsetList);
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "%a, load formset from HII handle: 0x%x failed: %r\n", __FUNCTION__, Target->HiiHandle, Status));
- }
- }
-
- //
- // Detach it from list first.
- //
- RemoveEntryList (&Target->Link);
- FreePool (Target);
-
- PendingListLink = 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 == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- if (IsListEmpty (&StatementList->StatementList)) {
- return EFI_SUCCESS;
- }
-
- NextLink = GetFirstNode (&StatementList->StatementList);
- while (!IsNull (&StatementList->StatementList, NextLink)) {
- StatementRef = REDFISH_PLATFORM_CONFIG_STATEMENT_REF_FROM_LINK (NextLink);
- NextLink = 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<BR>
+
+ 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 == NULL || StringId == 0) {
+ DEBUG ((DEBUG_INFO, "???"));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ String = HiiGetString (HiiHandle, StringId, NULL);
+ if (String == 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 == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Index = 0;
+ HiiFormLink = GetFirstNode (&FormsetPrivate->HiiFormList);
+ while (!IsNull (&FormsetPrivate->HiiFormList, HiiFormLink)) {
+ HiiFormPrivate = REDFISH_PLATFORM_CONFIG_FORM_FROM_LINK (HiiFormLink);
+ HiiNextFormLink = GetNextNode (&FormsetPrivate->HiiFormList, HiiFormLink);
+
+ DEBUG ((DEBUG_INFO, " [%d] form: %d title: ", ++Index, HiiFormPrivate->Id));
+ DumpHiiString (FormsetPrivate->HiiHandle, HiiFormPrivate->Title);
+ DEBUG ((DEBUG_INFO, "\n"));
+
+ HiiStatementLink = GetFirstNode (&HiiFormPrivate->StatementList);
+ while (!IsNull (&HiiFormPrivate->StatementList, HiiStatementLink)) {
+ HiiStatementPrivate = REDFISH_PLATFORM_CONFIG_STATEMENT_FROM_LINK (HiiStatementLink);
+ HiiNextStatementLink = GetNextNode (&HiiFormPrivate->StatementList, HiiStatementLink);
+
+ DEBUG ((DEBUG_INFO, " QID: 0x%x Prompt: ", HiiStatementPrivate->QuestionId));
+ DumpHiiString (FormsetPrivate->HiiHandle, HiiStatementPrivate->Description);
+ DEBUG ((DEBUG_INFO, "\n"));
+
+ HiiStatementLink = HiiNextStatementLink;
+ }
+
+ HiiFormLink = 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 == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (IsListEmpty (FormsetList)) {
+ DEBUG ((DEBUG_INFO, "%a, Empty formset list\n", __FUNCTION__));
+ return EFI_SUCCESS;
+ }
+
+ Index = 0;
+ HiiFormsetLink = GetFirstNode (FormsetList);
+ while (!IsNull (FormsetList, HiiFormsetLink)) {
+ HiiFormsetNextLink = GetNextNode (FormsetList, HiiFormsetLink);
+ HiiFormsetPrivate = REDFISH_PLATFORM_CONFIG_FORMSET_FROM_LINK (HiiFormsetLink);
+
+ DEBUG ((DEBUG_INFO, "[%d] HII Handle: 0x%x formset: %g at %s\n", ++Index, HiiFormsetPrivate->HiiHandle, &HiiFormsetPrivate->Guid, HiiFormsetPrivate->DevicePathStr));
+ DumpFormset (HiiFormsetPrivate);
+
+ HiiFormsetLink = 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 responsible
+ 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 string 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 == NULL || HiiHandle == NULL || StringId == 0 || IS_EMPTY_STRING (Language)) {
+ ASSERT (FALSE);
+ return NULL;
+ }
+
+ //
+ // Retrieve the size of the string in the string package for the BestLanguage
+ //
+ StringSize = 0;
+ Status = 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 GetString()
+ // returns an error other than EFI_BUFFER_TOO_SMALL, then HiiHandle is not present
+ // in the HII Database
+ //
+ if (Status != EFI_BUFFER_TOO_SMALL) {
+ return NULL;
+ }
+
+ //
+ // Allocate a buffer for the return string
+ //
+ String = AllocateZeroPool (StringSize);
+ if (String == NULL) {
+ return NULL;
+ }
+
+ //
+ // Retrieve the string from the string package
+ //
+ Status = 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 = NULL;
+ }
+
+ //
+ // Return the Null-terminated Unicode string
+ //
+ return String;
+}
+
+/**
+ Retrieves a string from a string package in a English language. The
+ returned string is allocated using AllocatePool(). The caller is responsible
+ 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 string 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 = HiiGetRedfishString (HiiHandle, Language, StringId);
+ if (HiiString == NULL) {
+ DEBUG ((DEBUG_ERROR, "%a, Can not find string ID: 0x%x with %a\n", __FUNCTION__, StringId, Language));
+ return NULL;
+ }
+
+ StringSize = (StrLen (HiiString) + 1) * sizeof (CHAR8);
+ AsciiString = AllocatePool (StringSize);
+ if (AsciiString == 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 string 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 otherwise.
+
+**/
+BOOLEAN
+CheckSupportedSchema (
+ IN REDFISH_PLATFORM_CONFIG_SCHEMA *SupportedSchema,
+ IN CHAR8 *Schema
+ )
+{
+ UINTN Index;
+
+ if (SupportedSchema == NULL || IS_EMPTY_STRING (Schema)) {
+ return FALSE;
+ }
+
+ if (SupportedSchema->Count == 0) {
+ return FALSE;
+ }
+
+ for (Index = 0; Index < SupportedSchema->Count; Index++) {
+ if (AsciiStrCmp (SupportedSchema->SchemaList[Index], Schema) == 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 NULL.
+ @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 == NULL || SupportedSchema == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ SupportedSchema->Count = 0;
+
+ SupportedLanguages = HiiGetSupportedLanguages (HiiHandle);
+ if (SupportedLanguages == NULL) {
+ return EFI_NOT_FOUND;
+ }
+
+ Index = 0;
+ LangIndex = 0;
+ Count = 0;
+ while (TRUE) {
+ if (SupportedLanguages[Index] == ';' || SupportedLanguages[Index] == '\0') {
+ if (AsciiStrnCmp (&SupportedLanguages[LangIndex], X_UEFI_SCHEMA_PREFIX, AsciiStrLen (X_UEFI_SCHEMA_PREFIX)) == 0) {
+ ++Count;
+ }
+ LangIndex = Index + 1;
+ }
+
+ if (SupportedLanguages[Index] == '\0') {
+ break;
+ }
+
+ ++Index;
+ }
+
+ if (Count == 0) {
+ return EFI_NOT_FOUND;
+ }
+
+ SupportedSchema->Count = Count;
+ SupportedSchema->SchemaList = AllocatePool (sizeof (CHAR8 *) * Count);
+ if (SupportedSchema->SchemaList == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ Index = 0;
+ LangIndex = 0;
+ ListIndex = 0;
+ while (TRUE) {
+
+ if (SupportedLanguages[Index] == ';' || SupportedLanguages[Index] == '\0') {
+ if (AsciiStrnCmp (&SupportedLanguages[LangIndex], X_UEFI_SCHEMA_PREFIX, AsciiStrLen (X_UEFI_SCHEMA_PREFIX)) == 0) {
+ StrSize = Index - LangIndex;
+ SupportedSchema->SchemaList[ListIndex] = AllocateCopyPool ((StrSize + 1), &SupportedLanguages[LangIndex]);
+ SupportedSchema->SchemaList[ListIndex][StrSize] = '\0';
+ ++ListIndex;
+ }
+
+ LangIndex = Index + 1;
+ }
+
+ if (SupportedLanguages[Index] == '\0') {
+ break;
+ }
+
+ ++Index;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Search and find statement private instance by given regular expression patthern
+ 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 *RegularExpressionProtocol,
+ 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 == NULL || IS_EMPTY_STRING (Schema) || IS_EMPTY_STRING (Pattern) || StatementList == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (RegularExpressionProtocol == NULL) {
+ return EFI_NOT_READY;
+ }
+
+ StatementList->Count = 0;
+ InitializeListHead (&StatementList->StatementList);
+
+ if (IsListEmpty (FormsetList)) {
+ return EFI_NOT_FOUND;
+ }
+
+ HiiFormsetLink = GetFirstNode (FormsetList);
+ while (!IsNull (FormsetList, HiiFormsetLink)) {
+ HiiFormsetNextLink = GetNextNode (FormsetList, HiiFormsetLink);
+ HiiFormsetPrivate = REDFISH_PLATFORM_CONFIG_FORMSET_FROM_LINK (HiiFormsetLink);
+
+ //
+ // Performance check.
+ // If there is no desired Redfish schema found, skip this formset.
+ //
+ if (!CheckSupportedSchema (&HiiFormsetPrivate->SupportedSchema, Schema)) {
+ HiiFormsetLink = HiiFormsetNextLink;
+ continue;
+ }
+
+ HiiFormLink = GetFirstNode (&HiiFormsetPrivate->HiiFormList);
+ while (!IsNull (&HiiFormsetPrivate->HiiFormList, HiiFormLink)) {
+ HiiNextFormLink = GetNextNode (&HiiFormsetPrivate->HiiFormList, HiiFormLink);
+ HiiFormPrivate = REDFISH_PLATFORM_CONFIG_FORM_FROM_LINK (HiiFormLink);
+
+ HiiStatementLink =GetFirstNode (&HiiFormPrivate->StatementList);
+ while (!IsNull (&HiiFormPrivate->StatementList, HiiStatementLink)) {
+ HiiNextStatementLink = GetNextNode (&HiiFormPrivate->StatementList, HiiStatementLink);
+ HiiStatementPrivate = REDFISH_PLATFORM_CONFIG_STATEMENT_FROM_LINK (HiiStatementLink);
+
+ if (HiiStatementPrivate->Description != 0) {
+ TmpString = HiiGetRedfishString (HiiFormsetPrivate->HiiHandle, Schema, HiiStatementPrivate->Description);
+ if (TmpString != NULL) {
+ Status = RegularExpressionProtocol->MatchString (
+ RegularExpressionProtocol,
+ TmpString,
+ Pattern,
+ &gEfiRegexSyntaxTypePerlGuid,
+ &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 = AllocateZeroPool (sizeof (REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_REF));
+ if (StatementRef == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ StatementRef->Statement = HiiStatementPrivate;
+ InsertTailList (&StatementList->StatementList, &StatementRef->Link);
+ ++StatementList->Count;
+ }
+
+ FreePool (TmpString);
+ }
+ }
+
+ HiiStatementLink = HiiNextStatementLink;
+ }
+
+ HiiFormLink = HiiNextFormLink;
+ }
+
+ HiiFormsetLink = 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 statement 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 == NULL || IS_EMPTY_STRING (Schema) || IS_EMPTY_STRING (ConfigureLang)) {
+ return NULL;
+ }
+
+ if (IsListEmpty (FormsetList)) {
+ return NULL;
+ }
+
+ HiiFormsetLink = GetFirstNode (FormsetList);
+ while (!IsNull (FormsetList, HiiFormsetLink)) {
+ HiiFormsetNextLink = GetNextNode (FormsetList, HiiFormsetLink);
+ HiiFormsetPrivate = REDFISH_PLATFORM_CONFIG_FORMSET_FROM_LINK (HiiFormsetLink);
+
+ //
+ // Performance check.
+ // If there is no desired Redfish schema found, skip this formset.
+ //
+ if (!CheckSupportedSchema (&HiiFormsetPrivate->SupportedSchema, Schema)) {
+ HiiFormsetLink = HiiFormsetNextLink;
+ continue;
+ }
+
+ HiiFormLink = GetFirstNode (&HiiFormsetPrivate->HiiFormList);
+ while (!IsNull (&HiiFormsetPrivate->HiiFormList, HiiFormLink)) {
+ HiiNextFormLink = GetNextNode (&HiiFormsetPrivate->HiiFormList, HiiFormLink);
+ HiiFormPrivate = REDFISH_PLATFORM_CONFIG_FORM_FROM_LINK (HiiFormLink);
+
+ HiiStatementLink =GetFirstNode (&HiiFormPrivate->StatementList);
+ while (!IsNull (&HiiFormPrivate->StatementList, HiiStatementLink)) {
+ HiiNextStatementLink = GetNextNode (&HiiFormPrivate->StatementList, HiiStatementLink);
+ HiiStatementPrivate = REDFISH_PLATFORM_CONFIG_STATEMENT_FROM_LINK (HiiStatementLink);
+
+ DEBUG_CODE (
+ STATIC UINTN Index = 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 != 0) {
+ TmpString = HiiGetRedfishString (HiiFormsetPrivate->HiiHandle, Schema, HiiStatementPrivate->Description);
+ if (TmpString != NULL) {
+ if (StrCmp (TmpString, ConfigureLang) == 0) {
+ FreePool (TmpString);
+ return HiiStatementPrivate;
+ }
+
+ FreePool (TmpString);
+ }
+ }
+
+ HiiStatementLink = HiiNextStatementLink;
+ }
+
+ HiiFormLink = HiiNextFormLink;
+ }
+
+ HiiFormsetLink = 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 == NULL || FormsetList == NULL) {
+ return NULL;
+ }
+
+ if (IsListEmpty (FormsetList)) {
+ return NULL;
+ }
+
+ HiiFormsetLink = GetFirstNode (FormsetList);
+ while (!IsNull (FormsetList, HiiFormsetLink)) {
+ HiiFormsetNextLink = GetNextNode (FormsetList, HiiFormsetLink);
+ HiiFormsetPrivate = REDFISH_PLATFORM_CONFIG_FORMSET_FROM_LINK (HiiFormsetLink);
+
+ if (HiiFormsetPrivate->HiiHandle == HiiHandle) {
+ return HiiFormsetPrivate;
+ }
+
+ HiiFormsetLink = HiiFormsetNextLink;
+ }
+
+ return NULL;
+}
+
+/**
+ Release formset and all the forms and statements that belong to this formset.
+
+ @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 == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ HiiFormLink = GetFirstNode (&FormsetPrivate->HiiFormList);
+ while (!IsNull (&FormsetPrivate->HiiFormList, HiiFormLink)) {
+ HiiFormPrivate = REDFISH_PLATFORM_CONFIG_FORM_FROM_LINK (HiiFormLink);
+ HiiNextFormLink = GetNextNode (&FormsetPrivate->HiiFormList, HiiFormLink);
+
+ HiiStatementLink = GetFirstNode (&HiiFormPrivate->StatementList);
+ while (!IsNull (&HiiFormPrivate->StatementList, HiiStatementLink)) {
+ HiiStatementPrivate = REDFISH_PLATFORM_CONFIG_STATEMENT_FROM_LINK (HiiStatementLink);
+ HiiNextStatementLink = GetNextNode (&HiiFormPrivate->StatementList, HiiStatementLink);
+
+ //
+ // HiiStatementPrivate->HiiStatement will be released in DestroyFormSet().
+ //
+
+ if (HiiStatementPrivate->DesStringCache != NULL) {
+ FreePool (HiiStatementPrivate->DesStringCache);
+ HiiStatementPrivate->DesStringCache = NULL;
+ }
+
+ RemoveEntryList (&HiiStatementPrivate->Link);
+ FreePool (HiiStatementPrivate);
+ HiiStatementLink = HiiNextStatementLink;
+ }
+
+ //
+ // HiiStatementPrivate->HiiForm will be released in DestroyFormSet().
+ //
+
+ RemoveEntryList (&HiiFormPrivate->Link);
+ FreePool (HiiFormPrivate);
+ HiiFormLink = HiiNextFormLink;
+ }
+
+ if (FormsetPrivate->HiiFormSet != NULL) {
+ DestroyFormSet (FormsetPrivate->HiiFormSet);
+ FormsetPrivate->HiiFormSet = NULL;
+ }
+
+ if (FormsetPrivate->DevicePathStr != NULL) {
+ FreePool(FormsetPrivate->DevicePathStr);
+ }
+
+ //
+ // Release schema list
+ //
+ if (FormsetPrivate->SupportedSchema.SchemaList != NULL) {
+ for (Index = 0; Index < FormsetPrivate->SupportedSchema.Count; Index++) {
+ FreePool (FormsetPrivate->SupportedSchema.SchemaList[Index]);
+ }
+
+ FreePool (FormsetPrivate->SupportedSchema.SchemaList);
+ FormsetPrivate->SupportedSchema.SchemaList = NULL;
+ FormsetPrivate->SupportedSchema.Count = 0;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Create new form-set instance.
+
+ @retval REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE * Pointer to newly created form-set private instance.
+
+**/
+REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *
+NewFormsetPrivate (
+ VOID
+ )
+{
+ REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *NewFormsetPrivate;
+
+ NewFormsetPrivate = AllocateZeroPool (sizeof (REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE));
+ if (NewFormsetPrivate == 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 == NULL || FormsetPrivate == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+
+ HiiFormSet = AllocateZeroPool (sizeof (HII_FORMSET));
+ if (HiiFormSet == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ //
+ // Find HII formset by the given HII handle.
+ //
+ ZeroMem (&ZeroGuid, sizeof (ZeroGuid));
+ Status = CreateFormSetFromHiiHandle (HiiHandle, &ZeroGuid, HiiFormSet);
+ if (EFI_ERROR (Status) || IsListEmpty (&HiiFormSet->FormListHead)) {
+ Status = EFI_NOT_FOUND;
+ goto ErrorExit;
+ }
+
+ //
+ // Initialize formset
+ //
+ InitializeFormSet (HiiFormSet);
+
+ //
+ // Initialize formset private data.
+ //
+ FormsetPrivate->HiiFormSet = HiiFormSet;
+ FormsetPrivate->HiiHandle = HiiHandle;
+ CopyGuid (&FormsetPrivate->Guid, &HiiFormSet->Guid);
+ FormsetPrivate->DevicePathStr = ConvertDevicePathToText (HiiFormSet->DevicePath, FALSE, FALSE);
+ Status = GetSupportedSchema (FormsetPrivate->HiiHandle, &FormsetPrivate->SupportedSchema);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_WARN, "%a, No schema from HII handle: 0x%x found: %r\n", __FUNCTION__, FormsetPrivate->HiiHandle, Status));
+ }
+
+ HiiFormLink = GetFirstNode (&HiiFormSet->FormListHead);
+ while (!IsNull (&HiiFormSet->FormListHead, HiiFormLink)) {
+ HiiForm = HII_FORM_FROM_LINK (HiiFormLink);
+
+ HiiFormPrivate = AllocateZeroPool (sizeof (REDFISH_PLATFORM_CONFIG_FORM_PRIVATE));
+ if (HiiFormPrivate == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto ErrorExit;
+ }
+
+ //
+ // Initialize form private data.
+ //
+ HiiFormPrivate->HiiForm = HiiForm;
+ HiiFormPrivate->Id = HiiForm->FormId;
+ HiiFormPrivate->Title = HiiForm->FormTitle;
+ HiiFormPrivate->ParentFormset = FormsetPrivate;
+ InitializeListHead (&HiiFormPrivate->StatementList);
+
+ HiiStatementLink = GetFirstNode (&HiiForm->StatementListHead);
+ while (!IsNull (&HiiForm->StatementListHead, HiiStatementLink)) {
+ HiiStatement = HII_STATEMENT_FROM_LINK (HiiStatementLink);
+
+ HiiStatementPrivate = AllocateZeroPool (sizeof (REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE));
+ if (HiiStatementPrivate == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto ErrorExit;
+ }
+ //
+ // Initialize statement private data.
+ //
+ HiiStatementPrivate->HiiStatement = HiiStatement;
+ HiiStatementPrivate->QuestionId = HiiStatement->QuestionId;
+ HiiStatementPrivate->Description = HiiStatement->Prompt;
+ HiiStatementPrivate->ParentForm = HiiFormPrivate;
+
+ //
+ // Attach to statement list.
+ //
+ InsertTailList (&HiiFormPrivate->StatementList, &HiiStatementPrivate->Link);
+ HiiStatementLink = GetNextNode (&HiiForm->StatementListHead, HiiStatementLink);
+ }
+ //
+ // Attach to form list.
+ //
+ InsertTailList (&FormsetPrivate->HiiFormList, &HiiFormPrivate->Link);
+ HiiFormLink = GetNextNode (&HiiFormSet->FormListHead, HiiFormLink);
+ }
+
+ return EFI_SUCCESS;
+
+ErrorExit:
+
+ //
+ // Release HiiFormSet if HiiFormSet is not linked to FormsetPrivate yet.
+ //
+ if (HiiFormSet != NULL && FormsetPrivate->HiiFormSet != 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 == NULL || FormsetList == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ FormsetPrivate = GetFormsetPrivateByHiiHandle (HiiHandle, FormsetList);
+ if (FormsetPrivate != NULL) {
+ return EFI_ALREADY_STARTED;
+ }
+
+ FormsetPrivate = NewFormsetPrivate ();
+ if (FormsetPrivate == NULL) {
+ DEBUG ((DEBUG_ERROR, "%a, out of resource\n", __FUNCTION__));
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ //
+ // Load formset on the given HII handle.
+ //
+ Status = 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 == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (IsListEmpty (FormsetList)) {
+ return EFI_SUCCESS;
+ }
+
+ HiiFormsetLink = GetFirstNode (FormsetList);
+ while (!IsNull (FormsetList, HiiFormsetLink)) {
+ HiiFormsetNextLink = GetNextNode (FormsetList, HiiFormsetLink);
+ HiiFormsetPrivate = REDFISH_PLATFORM_CONFIG_FORMSET_FROM_LINK (HiiFormsetLink);
+
+ //
+ // Detach from list.
+ //
+ RemoveEntryList (&HiiFormsetPrivate->Link);
+ ReleaseFormset (HiiFormsetPrivate);
+ FreePool (HiiFormsetPrivate);
+ HiiFormsetLink = 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 == NULL || PendingList == NULL) {
+ return NULL;
+ }
+
+ if (IsListEmpty (PendingList)) {
+ return NULL;
+ }
+
+ PendingListLink = GetFirstNode (PendingList);
+ while (!IsNull (PendingList, PendingListLink)) {
+ Target = REDFISH_PLATFORM_CONFIG_PENDING_LIST_FROM_LINK (PendingListLink);
+
+ if (Target->HiiHandle == HiiHandle) {
+ return Target;
+ }
+
+ PendingListLink = 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 recently 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 == NULL || PendingList == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Check and see if this HII handle is processed already.
+ //
+ TargetPendingList = GetPendingList (HiiHandle, PendingList);
+ if (TargetPendingList != NULL) {
+ TargetPendingList->IsDeleted = FALSE;
+ DEBUG_CODE (
+ DEBUG ((DEBUG_INFO, "%a, HII handle: 0x%x is updated\n", __FUNCTION__, HiiHandle));
+ );
+ return EFI_SUCCESS;
+ }
+
+ TargetPendingList= AllocateZeroPool (sizeof (REDFISH_PLATFORM_CONFIG_PENDING_LIST));
+ if (TargetPendingList == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ TargetPendingList->HiiHandle = HiiHandle;
+ TargetPendingList->IsDeleted = 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 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 recently 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 == NULL || PendingList == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Check and see if this HII handle is processed already.
+ //
+ TargetPendingList = GetPendingList (HiiHandle, PendingList);
+ if (TargetPendingList != NULL) {
+ TargetPendingList->IsDeleted = TRUE;
+ DEBUG_CODE (
+ DEBUG ((DEBUG_INFO, "%a, HII handle: 0x%x is updated and deleted\n", __FUNCTION__, HiiHandle));
+ );
+ return EFI_SUCCESS;
+ }
+
+ TargetPendingList= AllocateZeroPool (sizeof (REDFISH_PLATFORM_CONFIG_PENDING_LIST));
+ if (TargetPendingList == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ TargetPendingList->HiiHandle = HiiHandle;
+ TargetPendingList->IsDeleted = 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 NULL.
+
+**/
+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 == NULL || PendingList == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (IsListEmpty (PendingList)) {
+ return EFI_SUCCESS;
+ }
+
+ PendingListLink = GetFirstNode (PendingList);
+ while (!IsNull (PendingList, PendingListLink)) {
+ PendingListNextLink = GetNextNode (PendingList, PendingListLink);
+ Target = REDFISH_PLATFORM_CONFIG_PENDING_LIST_FROM_LINK (PendingListLink);
+
+ if (Target->IsDeleted) {
+ //
+ // The HII resource on this HII handle is removed. Release the formset.
+ //
+ FormsetPrivate = GetFormsetPrivateByHiiHandle (Target->HiiHandle, FormsetList);
+ if (FormsetPrivate != NULL) {
+ DEBUG ((DEBUG_INFO, "%a, formset: %g is removed because driver release 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 already\n", __FUNCTION__, Target->HiiHandle));
+ }
+ } else {
+ //
+ // The HII resource on this HII handle is updated/removed.
+ //
+ FormsetPrivate = GetFormsetPrivateByHiiHandle (Target->HiiHandle, FormsetList);
+ if (FormsetPrivate != NULL) {
+ //
+ // HII formset already exist, release it and query again.
+ //
+ DEBUG ((DEBUG_INFO, "%a, formset: %g is updated. Release current formset\n", __FUNCTION__, &FormsetPrivate->Guid));
+ RemoveEntryList (&FormsetPrivate->Link);
+ ReleaseFormset (FormsetPrivate);
+ FreePool (FormsetPrivate);
+ }
+
+ Status = LoadFormsetList (Target->HiiHandle, FormsetList);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a, load formset from HII handle: 0x%x failed: %r\n", __FUNCTION__, Target->HiiHandle, Status));
+ }
+ }
+
+ //
+ // Detach it from list first.
+ //
+ RemoveEntryList (&Target->Link);
+ FreePool (Target);
+
+ PendingListLink = 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 == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (IsListEmpty (&StatementList->StatementList)) {
+ return EFI_SUCCESS;
+ }
+
+ NextLink = GetFirstNode (&StatementList->StatementList);
+ while (!IsNull (&StatementList->StatementList, NextLink)) {
+ StatementRef = REDFISH_PLATFORM_CONFIG_STATEMENT_REF_FROM_LINK (NextLink);
+ NextLink = 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..be2f63df8d 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<BR>
-
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#ifndef EDKII_REDFISH_PLATFORM_CONFIG_IMPL_H_
-#define EDKII_REDFISH_PLATFORM_CONFIG_IMPL_H_
-
-#include <Uefi.h>
-
-//
-// Libraries
-//
-#include <Library/BaseLib.h>
-#include <Library/BaseMemoryLib.h>
-#include <Library/DebugLib.h>
-#include <Library/DevicePathLib.h>
-#include <Library/HiiUtilityLib.h>
-#include <Library/HiiLib.h>
-#include <Library/MemoryAllocationLib.h>
-#include <Library/UefiBootServicesTableLib.h>
-#include <Library/UefiLib.h>
-
-#define REDFISH_PLATFORM_CONFIG_DELETE_EXPIRED_FORMSET 0x00
-#define IS_EMPTY_STRING(a) (a == NULL || a[0] == 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, REDFISH_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 formset data.
- EFI_GUID Guid; // Formset GUID.
- EFI_HII_HANDLE HiiHandle; // Hii Handle of this formset.
- 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 supported 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 token of form title.
- REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *ParentFormset;
- HII_FORM *HiiForm; // Pointer to HII form data.
- LIST_ENTRY StatementList; // Statement list that keep statement under this form.
-} REDFISH_PLATFORM_CONFIG_FORM_PRIVATE;
-
-#define REDFISH_PLATFORM_CONFIG_FORM_FROM_LINK(a) BASE_CR (a, REDFISH_PLATFORM_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 cache for search function.
-} REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE;
-
-#define REDFISH_PLATFORM_CONFIG_STATEMENT_FROM_LINK(a) BASE_CR (a, REDFISH_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, REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_REF, Link)
-
-//
-// Definition of REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_LIST
-//
-typedef struct {
- LIST_ENTRY StatementList; // List of REDFISH_PLATFORM_CONFIG_STATEMENT_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 recently 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 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 recently 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 statement 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 patthern
- 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 *RegularExpressionProtocol,
- 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 NULL.
-
-**/
-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 responsible
- 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 string 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<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef EDKII_REDFISH_PLATFORM_CONFIG_IMPL_H_
+#define EDKII_REDFISH_PLATFORM_CONFIG_IMPL_H_
+
+#include <Uefi.h>
+
+//
+// Libraries
+//
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/HiiUtilityLib.h>
+#include <Library/HiiLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiLib.h>
+
+#define IS_EMPTY_STRING(a) (a == NULL || a[0] == 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, REDFISH_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 formset data.
+ EFI_GUID Guid; // Formset GUID.
+ EFI_HII_HANDLE HiiHandle; // Hii Handle of this formset.
+ 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 supported 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 token of form title.
+ REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *ParentFormset;
+ HII_FORM *HiiForm; // Pointer to HII form data.
+ LIST_ENTRY StatementList; // Statement list that keep statement under this form.
+} REDFISH_PLATFORM_CONFIG_FORM_PRIVATE;
+
+#define REDFISH_PLATFORM_CONFIG_FORM_FROM_LINK(a) BASE_CR (a, REDFISH_PLATFORM_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 cache for search function.
+} REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE;
+
+#define REDFISH_PLATFORM_CONFIG_STATEMENT_FROM_LINK(a) BASE_CR (a, REDFISH_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, REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_REF, Link)
+
+//
+// Definition of REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_LIST
+//
+typedef struct {
+ LIST_ENTRY StatementList; // List of REDFISH_PLATFORM_CONFIG_STATEMENT_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 recently 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 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 recently 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 statement 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 patthern
+ 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 *RegularExpressionProtocol,
+ 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 NULL.
+
+**/
+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 responsible
+ 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 string 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 string from a string package in a English language. The
+ returned string is allocated using AllocatePool(). The caller is responsible
+ 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 string 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
--
2.32.0.windows.2
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [edk2-staging][PATCH v2 1/1] edk2/RedfishPkg: Update Redfish Platform Config Protocol
2022-07-24 13:19 [edk2-staging][PATCH v2 1/1] edk2/RedfishPkg: Update Redfish Platform Config Protocol Nickle Wang
@ 2022-07-24 13:46 ` Chang, Abner
2022-07-25 3:25 ` Nickle Wang
0 siblings, 1 reply; 3+ messages in thread
From: Chang, Abner @ 2022-07-24 13:46 UTC (permalink / raw)
To: Nickle Wang, devel@edk2.groups.io; +Cc: Yang, Atom, Nick Ramirez
[AMD Official Use Only - General]
Thanks Nickle. Two comments in the below.
> -----Original Message-----
> From: Nickle Wang <nickle.wang@hpe.com>
> Sent: Sunday, July 24, 2022 9:20 PM
> To: devel@edk2.groups.io
> Cc: Chang, Abner <Abner.Chang@amd.com>; Yang, Atom
> <Atom.Yang@amd.com>; Nick Ramirez <nramirez@nvidia.com>
> Subject: [edk2-staging][PATCH v2 1/1] edk2/RedfishPkg: Update Redfish
> Platform Config Protocol
>
> [CAUTION: External Email]
>
> 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 <nickle.wang@hpe.com>
> Cc: Abner Chang <abner.chang@amd.com>
> Cc: Yang Atom <Atom.Yang@amd.com>
> Cc: Nick Ramirez <nramirez@nvidia.com>
> ---
> .../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/RedfishPkg/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<BR>
> -
> - 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_PLATFORM_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 = 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_CONFIG_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 configure
> 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_CONFIG_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 configure
> 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 given
> Schema and Pattern.
> -
> - @param[in] This Pointer to
> EDKII_REDFISH_PLATFORM_CONFIG_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
> ConfigureLangList.
> -
> - @retval EFI_SUCCESS ConfigureLangList is returned successfully.
> - @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_CONFIG_PROTOCOL instance.
> - @param[in] HiiHandle The target handle to search. If handle is NULL,
> - this function returns all schema from HII database.
> - @param[out] SupportedSchema The supported schema list which is
> separated 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 using 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, OPTIONAL
> - 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<BR>
> +
> + 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_PLATFORM_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 = 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_CONFIG_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 configure
> 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_CONFIG_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 configure
> 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
> given Schema and RegexPattern.
> +
> + @param[in] This Pointer to
> EDKII_REDFISH_PLATFORM_CONFIG_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
> ConfigureLangList.
> +
> + @retval EFI_SUCCESS ConfigureLangList is returned successfully.
> + @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_CONFIG_PROTOCOL instance.
> + @param[in] HiiHandle The target handle to search. If handle is NULL,
> + this function returns all schema from HII database.
> + @param[out] SupportedSchema The supported schema list which is
> separated 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 using 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, OPTIONAL
> + 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<BR>
> -
> - SPDX-License-Identifier: BSD-2-Clause-Patent
> -
> -**/
> -
> -#include "RedfishPlatformConfigDxe.h"
> -#include "RedfishPlatformConfigImpl.h"
> -
> -REDFISH_PLATFORM_CONFIG_PRIVATE *mRedfishPlatformConfigPrivate =
> 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 second value.
> - -1 is returned when second value is greater than first value.
> -
> -**/
> -UINTN
> -CompareHiiStatementValue (
> - IN HII_STATEMENT_VALUE *Value1,
> - IN HII_STATEMENT_VALUE *Value2
> - )
> -{
> - INTN Result;
> - UINT64 Data1;
> - UINT64 Data2;
> -
> - if (Value1 == NULL || Value2 == NULL) {
> - return 0xFF;
> - }
> -
> - switch (Value1->Type) {
> - case EFI_IFR_TYPE_NUM_SIZE_8:
> - Data1 = Value1->Value.u8;
> - break;
> - case EFI_IFR_TYPE_NUM_SIZE_16:
> - Data1 = Value1->Value.u16;
> - break;
> - case EFI_IFR_TYPE_NUM_SIZE_32:
> - Data1 = Value1->Value.u32;
> - break;
> - case EFI_IFR_TYPE_NUM_SIZE_64:
> - Data1 = Value1->Value.u64;
> - break;
> - case EFI_IFR_TYPE_BOOLEAN:
> - Data1 = (Value1->Value.b ? 1 : 0);
> - break;
> - default:
> - return 0xFF;
> - }
> -
> - switch (Value2->Type) {
> - case EFI_IFR_TYPE_NUM_SIZE_8:
> - Data2 = Value2->Value.u8;
> - break;
> - case EFI_IFR_TYPE_NUM_SIZE_16:
> - Data2 = Value2->Value.u16;
> - break;
> - case EFI_IFR_TYPE_NUM_SIZE_32:
> - Data2 = Value2->Value.u32;
> - break;
> - case EFI_IFR_TYPE_NUM_SIZE_64:
> - Data2 = Value2->Value.u64;
> - break;
> - case EFI_IFR_TYPE_BOOLEAN:
> - Data2 = (Value2->Value.b ? 1 : 0);
> - break;
> - default:
> - return 0xFF;
> - }
> -
> - Result = (Data1 == 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 != EFI_IFR_ONE_OF_OP) {
> - return 0;
> - }
> -
> - if (IsListEmpty (&Statement->HiiStatement->OptionListHead)) {
> - return 0;
> - }
> -
> - Link = GetFirstNode (&Statement->HiiStatement->OptionListHead);
> - while (!IsNull (&Statement->HiiStatement->OptionListHead, Link)) {
> - Option = HII_QUESTION_OPTION_FROM_LINK (Link);
> -
> - if (CompareHiiStatementValue (&Statement->HiiStatement->Value,
> &Option->Value) == 0) {
> - return Option->Text;
> - }
> -
> - Link = 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 == NULL || IS_EMPTY_STRING (HiiString) || Value == NULL) {
> - return EFI_INVALID_PARAMETER;
> - }
> -
> - if (Statement->HiiStatement->Operand != EFI_IFR_ONE_OF_OP) {
> - return EFI_UNSUPPORTED;
> - }
> -
> - if (IsListEmpty (&Statement->HiiStatement->OptionListHead)) {
> - return EFI_NOT_FOUND;
> - }
> -
> - Found = FALSE;
> - Link = GetFirstNode (&Statement->HiiStatement->OptionListHead);
> - while (!IsNull (&Statement->HiiStatement->OptionListHead, Link)) {
> - Option = HII_QUESTION_OPTION_FROM_LINK (Link);
> -
> - TmpString = HiiGetRedfishString (Statement->ParentForm-
> >ParentFormset->HiiHandle, Schema, Option->Text);
> - if (TmpString != NULL) {
> - if (StrCmp (TmpString, HiiString) == 0) {
> - CopyMem (Value, &Option->Value, sizeof (HII_STATEMENT_VALUE));
> - Found = TRUE;
> - }
> - FreePool (TmpString);
> - }
> -
> - if (Found) {
> - return EFI_SUCCESS;
> - }
> -
> - Link = 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 == NULL || RedfishValue == NULL) {
> - return EFI_INVALID_PARAMETER;
> - }
> -
> - switch (Value->Type) {
> - case EFI_IFR_TYPE_NUM_SIZE_8:
> - RedfishValue->Type = REDFISH_VALUE_TYPE_INTEGER;
> - RedfishValue->Value.Integer = (INT64)Value->Value.u8;
> - break;
> - case EFI_IFR_TYPE_NUM_SIZE_16:
> - RedfishValue->Type = REDFISH_VALUE_TYPE_INTEGER;
> - RedfishValue->Value.Integer = (INT64)Value->Value.u16;
> - break;
> - case EFI_IFR_TYPE_NUM_SIZE_32:
> - RedfishValue->Type = REDFISH_VALUE_TYPE_INTEGER;
> - RedfishValue->Value.Integer = (INT64)Value->Value.u32;
> - break;
> - case EFI_IFR_TYPE_NUM_SIZE_64:
> - RedfishValue->Type = REDFISH_VALUE_TYPE_INTEGER;
> - RedfishValue->Value.Integer = (INT64)Value->Value.u64;
> - break;
> - case EFI_IFR_TYPE_BOOLEAN:
> - RedfishValue->Type = REDFISH_VALUE_TYPE_BOOLEAN;
> - RedfishValue->Value.Boolean = Value->Value.b;
> - break;
> - default:
> - RedfishValue->Type = 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 == NULL || RedfishValue == NULL) {
> - return EFI_INVALID_PARAMETER;
> - }
> -
> - switch (RedfishValue->Type) {
> - case REDFISH_VALUE_TYPE_INTEGER:
> - Value->Type = EFI_IFR_TYPE_NUM_SIZE_64;
> - Value->Value.u64 = (UINT64)RedfishValue->Value.Integer;
> - break;
> - case REDFISH_VALUE_TYPE_BOOLEAN:
> - Value->Type = EFI_IFR_TYPE_BOOLEAN;
> - Value->Value.b = RedfishValue->Value.Boolean;
> - break;
> - default:
> - Value->Type = 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 = AsciiStrSize(CONFIGURE_LANGUAGE_PREFIX) + AsciiStrSize (Schema)
> + AsciiStrSize (Version);
> -
> - FullName = AllocatePool (Size);
> - if (FullName == NULL) {
> - DEBUG ((DEBUG_ERROR, "%a, out-of-resource\n", __FUNCTION__));
> - return NULL;
> - }
> -
> - AsciiSPrint (FullName, Size, "%a%a.%a", CONFIGURE_LANGUAGE_PREFIX,
> Schema, 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 refers 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
> *RedfishPlatformConfigPrivate,
> - 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 == NULL || IS_EMPTY_STRING (Schema)
> || IS_EMPTY_STRING (ConfigureLang) || Statement == NULL) {
> - return EFI_INVALID_PARAMETER;
> - }
> -
> - *Statement = NULL;
> -
> - Status = ProcessPendingList (&RedfishPlatformConfigPrivate->FormsetList,
> &RedfishPlatformConfigPrivate->PendingList);
> - if (EFI_ERROR (Status)) {
> - DEBUG ((DEBUG_ERROR, "%a, ProcessPendingList failure: %r\n",
> __FUNCTION__, Status));
> - return Status;
> - }
> -
> - TargetStatement = GetStatementPrivateByConfigureLang
> (&RedfishPlatformConfigPrivate->FormsetList, Schema, ConfigureLang);
> - if (TargetStatement == 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 = 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 ==
> EFI_IFR_TYPE_UNDEFINED) {
> - return EFI_DEVICE_ERROR;
> - }
> -
> - //
> - // Return Value.
> - //
> - *Statement = TargetStatement;
> -
> - return EFI_SUCCESS;
> -}
> -
> -/**
> - Get Redfish value with the given Schema and Configure Language.
> -
> - @param[in] This Pointer to
> EDKII_REDFISH_PLATFORM_CONFIG_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 configure
> 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 == NULL || IS_EMPTY_STRING (Schema) || IS_EMPTY_STRING
> (Version) || IS_EMPTY_STRING (ConfigureLang) || Value == NULL) {
> - return EFI_INVALID_PARAMETER;
> - }
> -
> - RedfishPlatformConfigPrivate =
> REDFISH_PLATFORM_CONFIG_PRIVATE_FROM_THIS (This);
> - Value->Type = REDFISH_VALUE_TYPE_UNKNOWN;
> - FullSchema = NULL;
> - HiiString = NULL;
> -
> - FullSchema = GetFullSchemaString (Schema, Version);
> - if (FullSchema == NULL) {
> - return EFI_OUT_OF_RESOURCES;
> - }
> -
> - Status = RedfishPlatformConfigGetStatementCommon
> (RedfishPlatformConfigPrivate, FullSchema, ConfigureLang,
> &TargetStatement);
> - if (EFI_ERROR (Status)) {
> - goto RELEASE_RESOURCE;
> - }
> -
> - switch (TargetStatement->HiiStatement->Operand) {
> - case EFI_IFR_ONE_OF_OP:
> - StringId = HiiValueToOneOfOptionStringId (TargetStatement);
> - if (StringId == 0) {
> - ASSERT (FALSE);
> - Status = EFI_DEVICE_ERROR;
> - goto RELEASE_RESOURCE;
> - }
> -
> - HiiString = HiiGetRedfishString (TargetStatement->ParentForm-
> >ParentFormset->HiiHandle, FullSchema, StringId);
> - if (HiiString == NULL) {
> - DEBUG ((DEBUG_ERROR, "%a, Can not find string ID: 0x%x with %a\n",
> __FUNCTION__, StringId, FullSchema));
> - Status = EFI_NOT_FOUND;
> - goto RELEASE_RESOURCE;
> - }
> -
> - Size = StrLen (HiiString) + 1;
> - Value->Value.Buffer = AllocatePool (Size);
> - if (Value->Value.Buffer == NULL) {
> - Status = EFI_OUT_OF_RESOURCES;
> - goto RELEASE_RESOURCE;
> - }
> -
> - UnicodeStrToAsciiStrS (HiiString, Value->Value.Buffer, Size);
> - Value->Type = REDFISH_VALUE_TYPE_STRING;
> -
> - break;
> - case EFI_IFR_STRING_OP:
> - if (TargetStatement->HiiStatement->Value.Type !=
> EFI_IFR_TYPE_STRING) {
> - ASSERT (FALSE);
> - Status = EFI_DEVICE_ERROR;
> - goto RELEASE_RESOURCE;
> - }
> -
> - Value->Type = REDFISH_VALUE_TYPE_STRING;
> - Value->Value.Buffer = AllocateCopyPool (StrSize ((CHAR16
> *)TargetStatement->HiiStatement->Value.Buffer), TargetStatement-
> >HiiStatement->Value.Buffer);
> - if (Value->Value.Buffer == NULL) {
> - Status = EFI_OUT_OF_RESOURCES;
> - goto RELEASE_RESOURCE;
> - }
> - break;
> - case EFI_IFR_CHECKBOX_OP:
> - case EFI_IFR_NUMERIC_OP:
> - Status = HiiValueToRedfishNumeric (&TargetStatement->HiiStatement-
> >Value, Value);
> - if (EFI_ERROR (Status)) {
> - DEBUG ((DEBUG_ERROR, "%a, failed to convert HII value to Redfish
> value: %r\n", __FUNCTION__, Status));
> - goto RELEASE_RESOURCE;
> - }
> - break;
> - default:
> - DEBUG ((DEBUG_ERROR, "%a, catch unsupported type: 0x%x! Please
> contact with author if we need to support this type.\n", __FUNCTION__,
> TargetStatement->HiiStatement->Operand));
> - ASSERT (FALSE);
> - Status = EFI_UNSUPPORTED;
> - goto RELEASE_RESOURCE;
> - }
> -
> -RELEASE_RESOURCE:
> -
> - if (FullSchema != NULL) {
> - FreePool (FullSchema);
> - }
> -
> - if (HiiString != 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 == NULL || HiiForm == NULL || HiiStatement == NULL ||
> Value == NULL) {
> - return EFI_INVALID_PARAMETER;
> - }
> -
> - Status = SetQuestionValue (
> - HiiFormset,
> - HiiForm,
> - HiiStatement,
> - Value
> - );
> - if (EFI_ERROR (Status)) {
> - DEBUG ((DEBUG_ERROR, "%a, failed to set question value: %r\n",
> __FUNCTION__, Status));
> - return Status;
> - }
> -
> - Status = 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 refers 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 == NULL || IS_EMPTY_STRING (Schema)
> || IS_EMPTY_STRING (ConfigureLang) || StatementValue == NULL) {
> - return EFI_INVALID_PARAMETER;
> - }
> -
> - TempBuffer = NULL;
> -
> - Status = ProcessPendingList (&RedfishPlatformConfigPrivate->FormsetList,
> &RedfishPlatformConfigPrivate->PendingList);
> - if (EFI_ERROR (Status)) {
> - DEBUG ((DEBUG_ERROR, "%a, ProcessPendingList failure: %r\n",
> __FUNCTION__, Status));
> - return Status;
> - }
> -
> - TargetStatement = GetStatementPrivateByConfigureLang
> (&RedfishPlatformConfigPrivate->FormsetList, Schema, ConfigureLang);
> - if (TargetStatement == 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 != 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 == EFI_IFR_ONE_OF_OP
> && StatementValue->Type == EFI_IFR_TYPE_STRING) {
> - TempBuffer = AllocatePool (StatementValue->BufferLen * sizeof
> (CHAR16));
> - if (TempBuffer == NULL) {
> - return EFI_OUT_OF_RESOURCES;
> - }
> -
> - AsciiStrToUnicodeStrS (StatementValue->Buffer, TempBuffer,
> StatementValue->BufferLen);
> - FreePool (StatementValue->Buffer);
> - StatementValue->Buffer = NULL;
> - StatementValue->BufferLen = 0;
> -
> - Status = HiiStringToOneOfOptionValue (TargetStatement, Schema,
> TempBuffer, 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 ==
> EFI_IFR_NUMERIC_OP && StatementValue->Type ==
> EFI_IFR_TYPE_NUM_SIZE_64) {
> - //
> - // Redfish only has numeric value type and it does not care about the
> value size.
> - // Do a patch here so we have proper value size applied.
> - //
> - StatementValue->Type = 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, TargetStatement->HiiStatement->Value.Type));
> - ASSERT (FALSE);
> - }
> - }
> -
> - Status = 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",
> __FUNCTION__, Status));
> - return Status;
> - }
> -
> - return EFI_SUCCESS;
> -}
> -
> -/**
> - Set Redfish value with the given Schema and Configure Language.
> -
> - @param[in] This Pointer to
> EDKII_REDFISH_PLATFORM_CONFIG_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 configure
> 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 == NULL || IS_EMPTY_STRING (Schema) || IS_EMPTY_STRING
> (Version) || IS_EMPTY_STRING (ConfigureLang)) {
> - return EFI_INVALID_PARAMETER;
> - }
> -
> - if (Value.Type == REDFISH_VALUE_TYPE_UNKNOWN || Value.Type >=
> REDFISH_VALUE_TYPE_MAX) {
> - return EFI_INVALID_PARAMETER;
> - }
> -
> - RedfishPlatformConfigPrivate =
> REDFISH_PLATFORM_CONFIG_PRIVATE_FROM_THIS (This);
> - FullSchema = NULL;
> -
> - FullSchema = GetFullSchemaString (Schema, Version);
> - if (FullSchema == 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 = RedfishNumericToHiiValue (&Value, &NewValue);
> - if (EFI_ERROR (Status)) {
> - DEBUG ((DEBUG_ERROR, "%a, failed to convert Redfish value to Hii
> value: %r\n", __FUNCTION__, Status));
> - goto RELEASE_RESOURCE;
> - }
> - break;
> - case REDFISH_VALUE_TYPE_STRING:
> - NewValue.Type = EFI_IFR_TYPE_STRING;
> - NewValue.BufferLen = (UINT16)AsciiStrSize (Value.Value.Buffer);
> - NewValue.Buffer = AllocateCopyPool (NewValue.BufferLen,
> Value.Value.Buffer);
> - if (NewValue.Buffer == NULL) {
> - Status = EFI_OUT_OF_RESOURCES;
> - goto RELEASE_RESOURCE;
> - }
> - break;
> - default:
> - ASSERT (FALSE);
> - break;
> - }
> -
> - Status = RedfishPlatformConfigSetStatementCommon
> (RedfishPlatformConfigPrivate, FullSchema, ConfigureLang, &NewValue);
> - if (EFI_ERROR (Status)) {
> - DEBUG ((DEBUG_ERROR, "%a, failed to set value to statement: %r\n",
> __FUNCTION__, Status));
> - }
> -
> -RELEASE_RESOURCE:
> -
> - if (FullSchema != NULL) {
> - FreePool (FullSchema);
> - }
> -
> - return Status;
> -}
> -
> -/**
> - Get the list of Configure Language from platform configuration by the given
> Schema and Pattern.
> -
> - @param[in] This Pointer to
> EDKII_REDFISH_PLATFORM_CONFIG_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
> ConfigureLangList.
> -
> - @retval EFI_SUCCESS ConfigureLangList is returned successfully.
> - @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
> *RedfishPlatformConfigPrivate;
> - 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 == NULL || IS_EMPTY_STRING (Schema) || IS_EMPTY_STRING
> (Version) || Count == NULL || ConfigureLangList == NULL ||
> IS_EMPTY_STRING (Pattern)) {
> - return EFI_INVALID_PARAMETER;
> - }
> -
> - *Count = 0;
> - *ConfigureLangList = NULL;
> - FullSchema = NULL;
> - RedfishPlatformConfigPrivate =
> REDFISH_PLATFORM_CONFIG_PRIVATE_FROM_THIS (This);
> -
> - Status = ProcessPendingList (&RedfishPlatformConfigPrivate->FormsetList,
> &RedfishPlatformConfigPrivate->PendingList);
> - if (EFI_ERROR (Status)) {
> - DEBUG ((DEBUG_ERROR, "%a, ProcessPendingList failure: %r\n",
> __FUNCTION__, Status));
> - return Status;
> - }
> -
> - FullSchema = GetFullSchemaString (Schema, Version);
> - if (FullSchema == NULL) {
> - return EFI_OUT_OF_RESOURCES;
> - }
> -
> - Status = GetStatementPrivateByConfigureLangRegex (
> - RedfishPlatformConfigPrivate->RegularExpressionProtocol,
> - &RedfishPlatformConfigPrivate->FormsetList,
> - FullSchema,
> - Pattern,
> - &StatementList
> - );
> - if (EFI_ERROR (Status)) {
> - DEBUG ((DEBUG_ERROR, "%a,
> GetStatementPrivateByConfigureLangRegex failure: %r\n", __FUNCTION__,
> Status));
> - goto RELEASE_RESOURCE;
> - }
> -
> - if (!IsListEmpty (&StatementList.StatementList)) {
> -
> - TmpConfigureLangList = AllocateZeroPool (sizeof (CHAR16 *) *
> StatementList.Count);
> - if (TmpConfigureLangList == NULL) {
> - Status = EFI_OUT_OF_RESOURCES;
> - goto RELEASE_RESOURCE;
> - }
> -
> - Index = 0;
> - NextLink = GetFirstNode (&StatementList.StatementList);
> - while (!IsNull (&StatementList.StatementList, NextLink)) {
> - StatementRef =
> REDFISH_PLATFORM_CONFIG_STATEMENT_REF_FROM_LINK (NextLink);
> - NextLink = GetNextNode (&StatementList.StatementList, NextLink);
> -
> - ASSERT (StatementRef->Statement->Description != 0);
> - if (StatementRef->Statement->Description != 0) {
> - TmpString = HiiGetRedfishString (StatementRef->Statement-
> >ParentForm->ParentFormset->HiiHandle, FullSchema, StatementRef-
> >Statement->Description);
> - ASSERT (TmpString != NULL);
> - if (TmpString != NULL) {
> - TmpConfigureLangList[Index] = AllocateCopyPool (StrSize (TmpString),
> TmpString);
> - ASSERT (TmpConfigureLangList[Index] != NULL);
> - FreePool (TmpString);
> - ++Index;
> - }
> - }
> - }
> - }
> -
> - *Count = StatementList.Count;
> - *ConfigureLangList = TmpConfigureLangList;
> -
> -RELEASE_RESOURCE:
> -
> - if (FullSchema != 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_CONFIG_PROTOCOL instance.
> - @param[in] HiiHandle The target handle to search. If handle is NULL,
> - this function return all schema from HII database.
> - @param[out] SupportedSchema The supported schema list which is
> separated by ';'.
> - The SupportedSchema is allocated by the callee. It's caller's
> - responsibility to free this buffer using 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 == NULL || SupportedSchema == NULL) {
> - return EFI_INVALID_PARAMETER;
> - }
> -
> - *SupportedSchema = NULL;
> -
> - RedfishPlatformConfigPrivate =
> REDFISH_PLATFORM_CONFIG_PRIVATE_FROM_THIS (This);
> -
> - Status = ProcessPendingList (&RedfishPlatformConfigPrivate->FormsetList,
> &RedfishPlatformConfigPrivate->PendingList);
> - if (EFI_ERROR (Status)) {
> - DEBUG ((DEBUG_ERROR, "%a, ProcessPendingList failure: %r\n",
> __FUNCTION__, Status));
> - return Status;
> - }
> -
> - if (IsListEmpty (&RedfishPlatformConfigPrivate->FormsetList)) {
> - return EFI_NOT_FOUND;
> - }
> -
> - //
> - // Calculate for string buffer size.
> - //
> - StringSize = 0;
> - HiiFormsetLink = GetFirstNode (&RedfishPlatformConfigPrivate-
> >FormsetList);
> - while (!IsNull (&RedfishPlatformConfigPrivate->FormsetList,
> HiiFormsetLink)) {
> - HiiFormsetNextLink = GetNextNode (&RedfishPlatformConfigPrivate-
> >FormsetList, HiiFormsetLink);
> - HiiFormsetPrivate =
> REDFISH_PLATFORM_CONFIG_FORMSET_FROM_LINK (HiiFormsetLink);
> -
> - if (HiiHandle != NULL && HiiHandle != HiiFormsetPrivate->HiiHandle) {
> - HiiFormsetLink = HiiFormsetNextLink;
> - continue;
> - }
> -
> - if (HiiFormsetPrivate->SupportedSchema.Count > 0) {
> - for (Index = 0; Index < HiiFormsetPrivate->SupportedSchema.Count;
> Index++) {
> - StringSize += AsciiStrSize (HiiFormsetPrivate-
> >SupportedSchema.SchemaList[Index]);
> - }
> - }
> -
> - HiiFormsetLink = HiiFormsetNextLink;
> - }
> -
> - if (StringSize == 0) {
> - return EFI_NOT_FOUND;
> - }
> -
> - StringBuffer = AllocatePool (StringSize);
> - if (StringBuffer == NULL) {
> - return EFI_OUT_OF_RESOURCES;
> - }
> -
> - StringIndex = 0;
> - HiiFormsetLink = GetFirstNode (&RedfishPlatformConfigPrivate-
> >FormsetList);
> - while (!IsNull (&RedfishPlatformConfigPrivate->FormsetList,
> HiiFormsetLink)) {
> - HiiFormsetNextLink = GetNextNode (&RedfishPlatformConfigPrivate-
> >FormsetList, HiiFormsetLink);
> - HiiFormsetPrivate =
> REDFISH_PLATFORM_CONFIG_FORMSET_FROM_LINK (HiiFormsetLink);
> -
> - if (HiiHandle != NULL && HiiHandle != HiiFormsetPrivate->HiiHandle) {
> - HiiFormsetLink = HiiFormsetNextLink;
> - continue;
> - }
> -
> - if (HiiFormsetPrivate->SupportedSchema.Count > 0) {
> - for (Index = 0; Index < HiiFormsetPrivate->SupportedSchema.Count;
> Index++) {
> - AsciiStrCpyS (&StringBuffer[StringIndex], (StringSize - StringIndex),
> HiiFormsetPrivate->SupportedSchema.SchemaList[Index]);
> - StringIndex += AsciiStrLen (HiiFormsetPrivate-
> >SupportedSchema.SchemaList[Index]);
> - StringBuffer[StringIndex] = ';';
> - ++StringIndex;
> - }
> - }
> -
> - HiiFormsetLink = HiiFormsetNextLink;
> - }
> -
> - StringBuffer[--StringIndex] = '\0';
> -
> - *SupportedSchema = 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 == EFI_HII_DATABASE_NOTIFY_NEW_PACK || NotifyType
> == EFI_HII_DATABASE_NOTIFY_ADD_PACK) {
> - //
> - // HII formset on this handle is updated by driver during run-time. The
> formset needs to be reloaded.
> - //
> - Status = NotifyFormsetUpdate (Handle, &mRedfishPlatformConfigPrivate-
> >PendingList);
> - if (EFI_ERROR (Status)) {
> - DEBUG ((DEBUG_ERROR, "%a, failed to notify updated formset of HII
> handle: 0x%x\n", __FUNCTION__, Handle));
> - return Status;
> - }
> - } else if (NotifyType == EFI_HII_DATABASE_NOTIFY_REMOVE_PACK) {
> - //
> - // HII resource is removed. The formset is no longer exist.
> - //
> - Status = NotifyFormsetDeleted (Handle,
> &mRedfishPlatformConfigPrivate->PendingList);
> - if (EFI_ERROR (Status)) {
> - DEBUG ((DEBUG_ERROR, "%a, failed to notify deleted formset of HII
> handle: 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 = 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 = 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 = 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 = mRedfishPlatformConfigPrivate->HiiDatabase-
> >RegisterPackageNotify (
> - mRedfishPlatformConfigPrivate->HiiDatabase,
> - EFI_HII_PACKAGE_FORMS,
> - NULL,
> - RedfishPlatformConfigFormUpdateNotify,
> - EFI_HII_DATABASE_NOTIFY_NEW_PACK,
> - &mRedfishPlatformConfigPrivate->NotifyHandle
> - );
> - if (EFI_ERROR (Status)) {
> - DEBUG ((DEBUG_ERROR, "%a, RegisterPackageNotify for
> EFI_HII_DATABASE_NOTIFY_NEW_PACK failure: %r\n", __FUNCTION__,
> Status));
> - }
> -
> - //
> - // Register package notification when new form package is updated.
> - //
> - Status = mRedfishPlatformConfigPrivate->HiiDatabase-
> >RegisterPackageNotify (
> - mRedfishPlatformConfigPrivate->HiiDatabase,
> - EFI_HII_PACKAGE_FORMS,
> - NULL,
> - RedfishPlatformConfigFormUpdateNotify,
> - EFI_HII_DATABASE_NOTIFY_ADD_PACK,
> - &mRedfishPlatformConfigPrivate->NotifyHandle
> - );
> - if (EFI_ERROR (Status)) {
> - DEBUG ((DEBUG_ERROR, "%a, RegisterPackageNotify for
> EFI_HII_DATABASE_NOTIFY_NEW_PACK failure: %r\n", __FUNCTION__,
> Status));
> - }
> -
> -#if REDFISH_PLATFORM_CONFIG_DELETE_EXPIRED_FORMSET
> - //
> - // Register package notification when new form package is removed.
> - //
> - Status = mRedfishPlatformConfigPrivate->HiiDatabase-
> >RegisterPackageNotify (
> - mRedfishPlatformConfigPrivate->HiiDatabase,
> - EFI_HII_PACKAGE_FORMS,
> - NULL,
> - RedfishPlatformConfigFormUpdateNotify,
> - EFI_HII_DATABASE_NOTIFY_REMOVE_PACK,
> - &mRedfishPlatformConfigPrivate->NotifyHandle
> - );
> - if (EFI_ERROR (Status)) {
> - DEBUG ((DEBUG_ERROR, "%a, RegisterPackageNotify for
> EFI_HII_DATABASE_NOTIFY_NEW_PACK failure: %r\n", __FUNCTION__,
> Status));
> - }
> -#endif
> -
> - gBS->CloseEvent (Event);
> - mRedfishPlatformConfigPrivate->HiiDbNotify.ProtocolEvent = 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 = gBS->LocateProtocol (
> - &gEfiRegularExpressionProtocolGuid,
> - NULL,
> - (VOID **)&mRedfishPlatformConfigPrivate-
> >RegularExpressionProtocol
> - );
> - if (EFI_ERROR (Status)) {
> - DEBUG ((DEBUG_ERROR, "%a, locate
> EFI_REGULAR_EXPRESSION_PROTOCOL failure: %r\n", __FUNCTION__,
> Status));
> - return;
> - }
> -
> - gBS->CloseEvent (Event);
> - mRedfishPlatformConfigPrivate->RegexNotify.ProtocolEvent = NULL;
> -
> -}
> -
> -/**
> - Unloads an image.
> -
> - @param ImageHandle Handle that identifies the image to be
> unloaded.
> -
> - @retval EFI_SUCCESS The image has been unloaded.
> - @retval EFI_INVALID_PARAMETER ImageHandle is not a valid image handle.
> -
> -**/
> -EFI_STATUS
> -EFIAPI
> -RedfishPlatformConfigDxeUnload (
> - IN EFI_HANDLE ImageHandle
> - )
> -{
> - EFI_STATUS Status;
> -
> - if (mRedfishPlatformConfigPrivate != NULL) {
> - Status = gBS->UninstallProtocolInterface (
> - mRedfishPlatformConfigPrivate->ImageHandle,
> - &gEdkIIRedfishPlatformConfigProtocolGuid,
> - (VOID*)&mRedfishPlatformConfigPrivate->Protocol
> - );
> - if (EFI_ERROR (Status)) {
> - DEBUG ((DEBUG_ERROR, "%a, can not uninstall
> gEdkIIRedfishPlatformConfigProtocolGuid: %r\n", __FUNCTION__, Status));
> - ASSERT (FALSE);
> - }
> -
> - //
> - // Close events
> - //
> - if (mRedfishPlatformConfigPrivate->HiiDbNotify.ProtocolEvent != NULL) {
> - gBS->CloseEvent (mRedfishPlatformConfigPrivate-
> >HiiDbNotify.ProtocolEvent);
> - }
> - if (mRedfishPlatformConfigPrivate->HiiStringNotify.ProtocolEvent != NULL)
> {
> - gBS->CloseEvent (mRedfishPlatformConfigPrivate-
> >HiiStringNotify.ProtocolEvent);
> - }
> - if (mRedfishPlatformConfigPrivate->RegexNotify.ProtocolEvent != NULL) {
> - gBS->CloseEvent (mRedfishPlatformConfigPrivate-
> >RegexNotify.ProtocolEvent);
> - }
> -
> - //
> - // Unregister package notification.
> - //
> - if (mRedfishPlatformConfigPrivate->NotifyHandle != NULL) {
> - mRedfishPlatformConfigPrivate->HiiDatabase->UnregisterPackageNotify
> (
> - mRedfishPlatformConfigPrivate->HiiDatabase,
> - mRedfishPlatformConfigPrivate->NotifyHandle
> - );
> - }
> -
> - ReleaseFormsetList (&mRedfishPlatformConfigPrivate->FormsetList);
> - FreePool (mRedfishPlatformConfigPrivate);
> - mRedfishPlatformConfigPrivate = 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 including
> - 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 = (REDFISH_PLATFORM_CONFIG_PRIVATE
> *)AllocateZeroPool (sizeof (REDFISH_PLATFORM_CONFIG_PRIVATE));
> - if (mRedfishPlatformConfigPrivate == NULL) {
> - DEBUG ((DEBUG_ERROR, "%a, can not allocate pool for
> REDFISH_PLATFORM_CONFIG_PRIVATE\n", __FUNCTION__));
> - ASSERT (FALSE);
> - return EFI_OUT_OF_RESOURCES;
> - }
> -
> - //
> - // Protocol initialization
> - //
> - mRedfishPlatformConfigPrivate->ImageHandle = ImageHandle;
> - mRedfishPlatformConfigPrivate->Protocol.GetValue =
> RedfishPlatformConfigProtocolGetValue;
> - mRedfishPlatformConfigPrivate->Protocol.SetValue =
> RedfishPlatformConfigProtocolSetValue;
> - mRedfishPlatformConfigPrivate->Protocol.GetConfigureLang =
> RedfishPlatformConfigProtocolGetConfigureLang;
> - mRedfishPlatformConfigPrivate->Protocol.GetSupportedSchema =
> RedfishPlatformConfigProtocolGetSupportedSchema;
> -
> - InitializeListHead (&mRedfishPlatformConfigPrivate->FormsetList);
> - InitializeListHead (&mRedfishPlatformConfigPrivate->PendingList);
> -
> - Status = gBS->InstallProtocolInterface (
> - &ImageHandle,
> - &gEdkIIRedfishPlatformConfigProtocolGuid,
> - EFI_NATIVE_INTERFACE,
> - (VOID*)&mRedfishPlatformConfigPrivate->Protocol
> - );
> - if (EFI_ERROR (Status)) {
> - DEBUG ((DEBUG_ERROR, "%a, can not install
> gEdkIIRedfishPlatformConfigProtocolGuid: %r\n", __FUNCTION__, Status));
> - ASSERT (FALSE);
> - }
> -
> - //
> - // Install protocol notification if HII database protocol is installed.
> - //
> - mRedfishPlatformConfigPrivate->HiiDbNotify.ProtocolEvent =
> EfiCreateProtocolNotifyEvent (
> - &gEfiHiiDatabaseProtocolGuid,
> - TPL_CALLBACK,
> - HiiDatabaseProtocolInstalled,
> - NULL,
> - &mRedfishPlatformConfigPrivate-
> >HiiDbNotify.Registration
> - );
> - if (mRedfishPlatformConfigPrivate->HiiDbNotify.ProtocolEvent == NULL) {
> - DEBUG ((DEBUG_ERROR, "%a, failed to create protocol notification for
> gEfiHiiDatabaseProtocolGuid\n", __FUNCTION__));
> - ASSERT (FALSE);
> - }
> -
> - //
> - // Install protocol notification if HII string protocol is installed.
> - //
> - mRedfishPlatformConfigPrivate->HiiStringNotify.ProtocolEvent =
> EfiCreateProtocolNotifyEvent (
> - &gEfiHiiStringProtocolGuid,
> - TPL_CALLBACK,
> - HiiStringProtocolInstalled,
> - NULL,
> - &mRedfishPlatformConfigPrivate-
> >HiiStringNotify.Registration
> - );
> - if (mRedfishPlatformConfigPrivate->HiiStringNotify.ProtocolEvent == NULL)
> {
> - DEBUG ((DEBUG_ERROR, "%a, failed to create protocol notification for
> gEfiHiiStringProtocolGuid\n", __FUNCTION__));
> - ASSERT (FALSE);
> - }
> -
> - //
> - // Install protocol notification if regular expression protocol is installed.
> - //
> - mRedfishPlatformConfigPrivate->RegexNotify.ProtocolEvent =
> EfiCreateProtocolNotifyEvent (
> - &gEfiRegularExpressionProtocolGuid,
> - TPL_CALLBACK,
> - RegexProtocolInstalled,
> - NULL,
> - &mRedfishPlatformConfigPrivate-
> >RegexNotify.Registration
> - );
> - if (mRedfishPlatformConfigPrivate->RegexNotify.ProtocolEvent == NULL) {
> - DEBUG ((DEBUG_ERROR, "%a, failed to create protocol notification for
> gEfiRegularExpressionProtocolGuid\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<BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include "RedfishPlatformConfigDxe.h"
> +#include "RedfishPlatformConfigImpl.h"
> +
> +REDFISH_PLATFORM_CONFIG_PRIVATE *mRedfishPlatformConfigPrivate =
> 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 = 0;
> + switch (Value->Type) {
> + case EFI_IFR_TYPE_NUM_SIZE_8:
> + Temp = Value->Value.u8;
> + break;
> +
> + case EFI_IFR_TYPE_NUM_SIZE_16:
> + Temp = Value->Value.u16;
> + break;
> +
> + case EFI_IFR_TYPE_NUM_SIZE_32:
> + Temp = Value->Value.u32;
> + break;
> +
> + case EFI_IFR_TYPE_BOOLEAN:
> + Temp = 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 buffer.
> +
> + @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 != NULL);
> +
> + switch (Type) {
> + case EFI_IFR_TYPE_NUM_SIZE_8:
> + *(((UINT8 *) Array) + Index) = (UINT8) Value;
> + break;
> +
> + case EFI_IFR_TYPE_NUM_SIZE_16:
> + *(((UINT16 *) Array) + Index) = (UINT16) Value;
> + break;
> +
> + case EFI_IFR_TYPE_NUM_SIZE_32:
> + *(((UINT32 *) Array) + Index) = (UINT32) Value;
> + break;
> +
> + case EFI_IFR_TYPE_NUM_SIZE_64:
> + *(((UINT64 *) Array) + Index) = (UINT64) Value;
> + break;
> +
> + default:
> + break;
> + }
> +}
> +
> +/**
> + Return data element in an Array by its Index in ordered list array buffer.
> +
> + @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 != NULL);
> +
> + Data = 0;
> + switch (Type) {
> + case EFI_IFR_TYPE_NUM_SIZE_8:
> + Data = (UINT64) *(((UINT8 *) Array) + Index);
> + break;
> +
> + case EFI_IFR_TYPE_NUM_SIZE_16:
> + Data = (UINT64) *(((UINT16 *) Array) + Index);
> + break;
> +
> + case EFI_IFR_TYPE_NUM_SIZE_32:
> + Data = (UINT64) *(((UINT32 *) Array) + Index);
> + break;
> +
> + case EFI_IFR_TYPE_NUM_SIZE_64:
> + Data = (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 == NULL) {
> + return 0;
> + }
> +
> + if (HiiStatement->Operand != EFI_IFR_ORDERED_LIST_OP) {
> + return 0;
> + }
> +
> + if (IsListEmpty (&HiiStatement->OptionListHead)) {
> + return 0;
> + }
> +
> + Found = FALSE;
> + Link = GetFirstNode (&HiiStatement->OptionListHead);
> + while (!IsNull (&HiiStatement->OptionListHead, Link)) {
> + Option = HII_QUESTION_OPTION_FROM_LINK (Link);
> +
> + CurrentValue = ExtendHiiValueToU64 (&Option->Value);
> + if (Value == CurrentValue) {
> + return Option->Text;
> + }
> +
> + Link = 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 second value.
> + -1 is returned when second value is greater than first value.
> +
> +**/
> +INTN
> +CompareHiiStatementValue (
> + IN HII_STATEMENT_VALUE *Value1,
> + IN HII_STATEMENT_VALUE *Value2
> + )
> +{
> + INTN Result;
> + UINT64 Data1;
> + UINT64 Data2;
> +
> + if (Value1 == NULL || Value2 == NULL) {
> + return -1;
> + }
> +
> + switch (Value1->Type) {
> + case EFI_IFR_TYPE_NUM_SIZE_8:
> + Data1 = Value1->Value.u8;
> + break;
> + case EFI_IFR_TYPE_NUM_SIZE_16:
> + Data1 = Value1->Value.u16;
> + break;
> + case EFI_IFR_TYPE_NUM_SIZE_32:
> + Data1 = Value1->Value.u32;
> + break;
> + case EFI_IFR_TYPE_NUM_SIZE_64:
> + Data1 = Value1->Value.u64;
> + break;
> + case EFI_IFR_TYPE_BOOLEAN:
> + Data1 = (Value1->Value.b ? 1 : 0);
> + break;
> + default:
> + return -1;
> + }
> +
> + switch (Value2->Type) {
> + case EFI_IFR_TYPE_NUM_SIZE_8:
> + Data2 = Value2->Value.u8;
> + break;
> + case EFI_IFR_TYPE_NUM_SIZE_16:
> + Data2 = Value2->Value.u16;
> + break;
> + case EFI_IFR_TYPE_NUM_SIZE_32:
> + Data2 = Value2->Value.u32;
> + break;
> + case EFI_IFR_TYPE_NUM_SIZE_64:
> + Data2 = Value2->Value.u64;
> + break;
> + case EFI_IFR_TYPE_BOOLEAN:
> + Data2 = (Value2->Value.b ? 1 : 0);
> + break;
> + default:
> + return -1;
> + }
> +
> + Result = (Data1 == 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 != EFI_IFR_ONE_OF_OP) {
> + return 0;
> + }
> +
> + if (IsListEmpty (&Statement->HiiStatement->OptionListHead)) {
> + return 0;
> + }
> +
> + Link = GetFirstNode (&Statement->HiiStatement->OptionListHead);
> + while (!IsNull (&Statement->HiiStatement->OptionListHead, Link)) {
> + Option = HII_QUESTION_OPTION_FROM_LINK (Link);
> +
> + if (CompareHiiStatementValue (&Statement->HiiStatement->Value,
> &Option->Value) == 0) {
> + return Option->Text;
> + }
> +
> + Link = 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 == NULL || IS_EMPTY_STRING (HiiString) || Value == NULL) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + if (Statement->HiiStatement->Operand != EFI_IFR_ONE_OF_OP) {
> + return EFI_UNSUPPORTED;
> + }
> +
> + if (IsListEmpty (&Statement->HiiStatement->OptionListHead)) {
> + return EFI_NOT_FOUND;
> + }
> +
> + Found = FALSE;
> + Link = GetFirstNode (&Statement->HiiStatement->OptionListHead);
> + while (!IsNull (&Statement->HiiStatement->OptionListHead, Link)) {
> + Option = HII_QUESTION_OPTION_FROM_LINK (Link);
> +
> + TmpString = HiiGetRedfishString (Statement->ParentForm-
> >ParentFormset->HiiHandle, Schema, Option->Text);
> + if (TmpString != NULL) {
> + if (StrCmp (TmpString, HiiString) == 0) {
> + CopyMem (Value, &Option->Value, sizeof (HII_STATEMENT_VALUE));
> + Found = TRUE;
> + }
> + FreePool (TmpString);
> + }
> +
> + if (Found) {
> + return EFI_SUCCESS;
> + }
> +
> + Link = 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 == NULL || RedfishValue == NULL) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + switch (Value->Type) {
> + case EFI_IFR_TYPE_NUM_SIZE_8:
> + RedfishValue->Type = REDFISH_VALUE_TYPE_INTEGER;
> + RedfishValue->Value.Integer = (INT64)Value->Value.u8;
> + break;
> + case EFI_IFR_TYPE_NUM_SIZE_16:
> + RedfishValue->Type = REDFISH_VALUE_TYPE_INTEGER;
> + RedfishValue->Value.Integer = (INT64)Value->Value.u16;
> + break;
> + case EFI_IFR_TYPE_NUM_SIZE_32:
> + RedfishValue->Type = REDFISH_VALUE_TYPE_INTEGER;
> + RedfishValue->Value.Integer = (INT64)Value->Value.u32;
> + break;
> + case EFI_IFR_TYPE_NUM_SIZE_64:
> + RedfishValue->Type = REDFISH_VALUE_TYPE_INTEGER;
> + RedfishValue->Value.Integer = (INT64)Value->Value.u64;
> + break;
> + case EFI_IFR_TYPE_BOOLEAN:
> + RedfishValue->Type = REDFISH_VALUE_TYPE_BOOLEAN;
> + RedfishValue->Value.Boolean = Value->Value.b;
> + break;
> + default:
> + RedfishValue->Type = 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 == NULL || RedfishValue == NULL) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + switch (RedfishValue->Type) {
> + case REDFISH_VALUE_TYPE_INTEGER:
> + Value->Type = EFI_IFR_TYPE_NUM_SIZE_64;
> + Value->Value.u64 = (UINT64)RedfishValue->Value.Integer;
> + break;
> + case REDFISH_VALUE_TYPE_BOOLEAN:
> + Value->Type = EFI_IFR_TYPE_BOOLEAN;
> + Value->Value.b = RedfishValue->Value.Boolean;
> + break;
> + default:
> + Value->Type = 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 == NULL || OrderedListStatement->Operand !=
> EFI_IFR_ORDERED_LIST_OP) {
> + return;
> + }
> +
> + DEBUG ((DEBUG_ERROR, "Value.Type= 0x%x\n", OrderedListStatement-
> >Value.Type));
> + DEBUG ((DEBUG_ERROR, "Value.BufferValueType= 0x%x\n",
> OrderedListStatement->Value.BufferValueType));
> + DEBUG ((DEBUG_ERROR, "Value.BufferLen= 0x%x\n",
> OrderedListStatement->Value.BufferLen));
> + DEBUG ((DEBUG_ERROR, "Value.Buffer= 0x%x\n", OrderedListStatement-
> >Value.Buffer));
> + DEBUG ((DEBUG_ERROR, "Value.MaxContainers= 0x%x\n",
> OrderedListStatement->ExtraData.OrderListData.MaxContainers));
> + DEBUG ((DEBUG_ERROR, "StorageWidth= 0x%x\n",
> OrderedListStatement->StorageWidth));
> +
> + if (OrderedListStatement->Value.Buffer == NULL) {
> + return;
> + }
> +
> + Value8 = NULL;
> + Value16 = NULL;
> + Value32 = NULL;
> + Value64 = NULL;
> + Count = 0;
> +
> + switch (OrderedListStatement->Value.BufferValueType) {
> + case EFI_IFR_TYPE_NUM_SIZE_8:
> + Value8 = (UINT8 *)OrderedListStatement->Value.Buffer;
> + Count = OrderedListStatement->StorageWidth / sizeof (UINT8);
> + for (Index = 0; Index < Count; Index++) {
> + DEBUG ((DEBUG_ERROR, "%d ", Value8[Index]));
> + }
> + break;
> + case EFI_IFR_TYPE_NUM_SIZE_16:
> + Value16 = (UINT16 *)OrderedListStatement->Value.Buffer;
> + Count = OrderedListStatement->StorageWidth / sizeof (UINT16);
> + for (Index = 0; Index < Count; Index++) {
> + DEBUG ((DEBUG_ERROR, "%d ", Value16[Index]));
> + }
> + break;
> + case EFI_IFR_TYPE_NUM_SIZE_32:
> + Value32 = (UINT32 *)OrderedListStatement->Value.Buffer;
> + Count = OrderedListStatement->StorageWidth / sizeof (UINT32);
> + for (Index = 0; Index < Count; Index++) {
> + DEBUG ((DEBUG_ERROR, "%d ", Value32[Index]));
> + }
> + break;
> + case EFI_IFR_TYPE_NUM_SIZE_64:
> + Value64 = (UINT64 *)OrderedListStatement->Value.Buffer;
> + Count = OrderedListStatement->StorageWidth / sizeof (UINT64);
> + for (Index = 0; Index < Count; Index++) {
> + DEBUG ((DEBUG_ERROR, "%d ", Value64[Index]));
> + }
> + break;
> + default:
> + Value8 = (UINT8 *)OrderedListStatement->Value.Buffer;
> + Count = OrderedListStatement->StorageWidth / sizeof (UINT8);
> + for (Index = 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 list.
> +
> +**/
> +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 == NULL || ReturnSize == NULL) {
> + return NULL;
> + }
> +
> + *ReturnSize = 0;
> +
> + if (Statement->HiiStatement->Operand != EFI_IFR_ORDERED_LIST_OP) {
> + return NULL;
> + }
> +
> + if (IsListEmpty (&Statement->HiiStatement->OptionListHead)) {
> + return NULL;
> + }
> +
> + DEBUG_CODE (
> + DumpOrderedListValue (Statement->HiiStatement);
> + );
> +
> + OptionCount = 0;
> + Link = GetFirstNode (&Statement->HiiStatement->OptionListHead);
> + while (!IsNull (&Statement->HiiStatement->OptionListHead, Link)) {
> + Option = HII_QUESTION_OPTION_FROM_LINK (Link);
> +
> + ++OptionCount;
> +
> + Link = GetNextNode (&Statement->HiiStatement->OptionListHead, Link);
> + }
> +
> + *ReturnSize = OptionCount;
> + ReturnedArray = AllocatePool (sizeof (EFI_STRING_ID) * OptionCount);
> + if (ReturnedArray == NULL) {
> + DEBUG ((DEBUG_ERROR, "%a, out of resource\n", __FUNCTION__));
> + *ReturnSize = 0;
> + return NULL;
> + }
> +
> + for (Index = 0; Index < OptionCount; Index++) {
> + Value = OrderedListGetArrayData (Statement->HiiStatement-
> >Value.Buffer, Statement->HiiStatement->Value.BufferValueType, Index);
> + ReturnedArray[Index] = 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 == NULL || IS_EMPTY_STRING (HiiString) || Value == NULL) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + *Value = 0;
> +
> + if (Statement->HiiStatement->Operand != EFI_IFR_ORDERED_LIST_OP) {
> + return EFI_UNSUPPORTED;
> + }
> +
> + if (IsListEmpty (&Statement->HiiStatement->OptionListHead)) {
> + return EFI_NOT_FOUND;
> + }
> +
> + Found = FALSE;
> + Link = GetFirstNode (&Statement->HiiStatement->OptionListHead);
> + while (!IsNull (&Statement->HiiStatement->OptionListHead, Link)) {
> + Option = HII_QUESTION_OPTION_FROM_LINK (Link);
> +
> + TmpString = HiiGetRedfishString (Statement->ParentForm-
> >ParentFormset->HiiHandle, Schema, Option->Text);
> + if (TmpString != NULL) {
> + if (StrCmp (TmpString, HiiString) == 0) {
> + *Value = ExtendHiiValueToU64 (&Option->Value);
> + Found = TRUE;
> + }
> + FreePool (TmpString);
> + }
> +
> + if (Found) {
> + return EFI_SUCCESS;
> + }
> +
> + Link = 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 == NULL || AsciiString[0] == '\0') {
> + return NULL;
> + }
> +
> + StringLen = AsciiStrLen (AsciiString) + 1;
> + Buffer = AllocatePool (StringLen * sizeof (CHAR16));
> + if (Buffer == NULL) {
> + return NULL;
> + }
> +
> + Status = 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 = AsciiStrSize(CONFIGURE_LANGUAGE_PREFIX) + AsciiStrSize
> (Schema) + AsciiStrSize (Version);
> +
> + FullName = AllocatePool (Size);
> + if (FullName == NULL) {
> + DEBUG ((DEBUG_ERROR, "%a, out-of-resource\n", __FUNCTION__));
> + return NULL;
> + }
> +
> + AsciiSPrint (FullName, Size, "%a%a.%a", CONFIGURE_LANGUAGE_PREFIX,
> Schema, 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 refers 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
> *RedfishPlatformConfigPrivate,
> + 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 == NULL || IS_EMPTY_STRING (Schema)
> || IS_EMPTY_STRING (ConfigureLang) || Statement == NULL) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + *Statement = NULL;
> +
> + Status = ProcessPendingList (&RedfishPlatformConfigPrivate->FormsetList,
> &RedfishPlatformConfigPrivate->PendingList);
> + if (EFI_ERROR (Status)) {
> + DEBUG ((DEBUG_ERROR, "%a, ProcessPendingList failure: %r\n",
> __FUNCTION__, Status));
> + return Status;
> + }
> +
> + TargetStatement = GetStatementPrivateByConfigureLang
> (&RedfishPlatformConfigPrivate->FormsetList, Schema, ConfigureLang);
> + if (TargetStatement == 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 = 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 ==
> EFI_IFR_TYPE_UNDEFINED) {
> + return EFI_DEVICE_ERROR;
> + }
> +
> + //
> + // Return Value.
> + //
> + *Statement = TargetStatement;
> +
> + return EFI_SUCCESS;
> +}
> +
> +/**
> + Get Redfish value with the given Schema and Configure Language.
> +
> + @param[in] This Pointer to
> EDKII_REDFISH_PLATFORM_CONFIG_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 configure
> 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 == NULL || IS_EMPTY_STRING (Schema) || IS_EMPTY_STRING
> (Version) || IS_EMPTY_STRING (ConfigureLang) || Value == NULL) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + RedfishPlatformConfigPrivate =
> REDFISH_PLATFORM_CONFIG_PRIVATE_FROM_THIS (This);
> + Value->Type = REDFISH_VALUE_TYPE_UNKNOWN;
> + Value->ArrayCount = 0;
> + Count = 0;
> + FullSchema = NULL;
> + HiiString = NULL;
> + StringIdArray = NULL;
> +
> + FullSchema = GetFullSchemaString (Schema, Version);
> + if (FullSchema == NULL) {
> + return EFI_OUT_OF_RESOURCES;
> + }
> +
> + Status = RedfishPlatformConfigGetStatementCommon
> (RedfishPlatformConfigPrivate, FullSchema, ConfigureLang,
> &TargetStatement);
> + if (EFI_ERROR (Status)) {
> + goto RELEASE_RESOURCE;
> + }
> +
> + switch (TargetStatement->HiiStatement->Operand) {
> + case EFI_IFR_ONE_OF_OP:
> + StringId = HiiValueToOneOfOptionStringId (TargetStatement);
> + if (StringId == 0) {
> + ASSERT (FALSE);
> + Status = EFI_DEVICE_ERROR;
> + goto RELEASE_RESOURCE;
> + }
> +
> + Value->Value.Buffer = HiiGetRedfishAsciiString (TargetStatement-
> >ParentForm->ParentFormset->HiiHandle, FullSchema, StringId);
> + if (Value->Value.Buffer == NULL) {
> + Status = EFI_OUT_OF_RESOURCES;
> + goto RELEASE_RESOURCE;
> + }
> +
> + Value->Type = REDFISH_VALUE_TYPE_STRING;
> + break;
> + case EFI_IFR_STRING_OP:
> + if (TargetStatement->HiiStatement->Value.Type !=
> EFI_IFR_TYPE_STRING) {
> + ASSERT (FALSE);
> + Status = EFI_DEVICE_ERROR;
> + goto RELEASE_RESOURCE;
> + }
> +
> + Value->Type = REDFISH_VALUE_TYPE_STRING;
> + Value->Value.Buffer = AllocatePool (StrLen ((CHAR16
> *)TargetStatement->HiiStatement->Value.Buffer) + 1);
> + UnicodeStrToAsciiStrS ((CHAR16 *)TargetStatement->HiiStatement-
> >Value.Buffer, Value->Value.Buffer, StrLen ((CHAR16 *)TargetStatement-
> >HiiStatement->Value.Buffer) + 1);
> + break;
> + case EFI_IFR_CHECKBOX_OP:
> + case EFI_IFR_NUMERIC_OP:
> + Status = HiiValueToRedfishNumeric (&TargetStatement->HiiStatement-
> >Value, Value);
> + if (EFI_ERROR (Status)) {
> + DEBUG ((DEBUG_ERROR, "%a, failed to convert HII value to Redfish
> value: %r\n", __FUNCTION__, Status));
> + goto RELEASE_RESOURCE;
> + }
> + break;
> + case EFI_IFR_ACTION_OP:
> + if (TargetStatement->HiiStatement->Value.Type !=
> EFI_IFR_TYPE_ACTION) {
> + ASSERT (FALSE);
> + Status = EFI_DEVICE_ERROR;
> + goto RELEASE_RESOURCE;
> + }
> +
> + //
> + // Action has no value. Just return unknown type.
> + //
> + Value->Type = REDFISH_VALUE_TYPE_UNKNOWN;
> + break;
> + case EFI_IFR_ORDERED_LIST_OP:
> + StringIdArray = HiiValueToOrderedListOptionStringId (TargetStatement,
> &Count);
> + if (StringIdArray == NULL) {
> + ASSERT (FALSE);
> + Status = EFI_DEVICE_ERROR;
> + goto RELEASE_RESOURCE;
> + }
> +
> + Value->Value.StringArray = AllocatePool (sizeof (CHAR8 *) * Count);
> + if (Value->Value.StringArray == NULL) {
> + ASSERT (FALSE);
> + Status = EFI_OUT_OF_RESOURCES;
> + goto RELEASE_RESOURCE;
> + }
> +
> + for (Index = 0; Index < Count; Index++) {
> + ASSERT (StringIdArray[Index] != 0);
> + Value->Value.StringArray[Index] = HiiGetRedfishAsciiString
> (TargetStatement->ParentForm->ParentFormset->HiiHandle, FullSchema,
> StringIdArray[Index]);
> + }
> +
> + Value->ArrayCount = Count;
> + Value->Type = REDFISH_VALUE_TYPE_STRING_ARRAY;
> + break;
> + default:
> + DEBUG ((DEBUG_ERROR, "%a, catch unsupported type: 0x%x! Please
> contact with author if we need to support this type.\n", __FUNCTION__,
> TargetStatement->HiiStatement->Operand));
> + ASSERT (FALSE);
> + Status = EFI_UNSUPPORTED;
> + goto RELEASE_RESOURCE;
> + }
> +
> +RELEASE_RESOURCE:
> +
> + if (FullSchema != NULL) {
> + FreePool (FullSchema);
> + }
> +
> + if (HiiString != NULL) {
> + FreePool (HiiString);
> + }
> +
> + if (StringIdArray != 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 == NULL || HiiForm == NULL || HiiStatement == NULL ||
> Value == NULL) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + Status = SetQuestionValue (
> + HiiFormset,
> + HiiForm,
> + HiiStatement,
> + Value
> + );
> + if (EFI_ERROR (Status)) {
> + DEBUG ((DEBUG_ERROR, "%a, failed to set question value: %r\n",
> __FUNCTION__, Status));
> + return Status;
> + }
> +
> + Status = 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 refers 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 == NULL || IS_EMPTY_STRING (Schema)
> || IS_EMPTY_STRING (ConfigureLang) || StatementValue == NULL) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + TempBuffer = NULL;
> + StringArray = NULL;
> +
> + Status = ProcessPendingList (&RedfishPlatformConfigPrivate->FormsetList,
> &RedfishPlatformConfigPrivate->PendingList);
> + if (EFI_ERROR (Status)) {
> + DEBUG ((DEBUG_ERROR, "%a, ProcessPendingList failure: %r\n",
> __FUNCTION__, Status));
> + return Status;
> + }
> +
> + TargetStatement = GetStatementPrivateByConfigureLang
> (&RedfishPlatformConfigPrivate->FormsetList, Schema, ConfigureLang);
> + if (TargetStatement == 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 != 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 == EFI_IFR_ONE_OF_OP
> && StatementValue->Type == EFI_IFR_TYPE_STRING) {
> +
> + TempBuffer = StrToUnicodeStr ((CHAR8 *)StatementValue->Buffer);
> + if (TempBuffer == NULL) {
> + return EFI_OUT_OF_RESOURCES;
> + }
> + FreePool (StatementValue->Buffer);
> + StatementValue->Buffer = NULL;
> + StatementValue->BufferLen = 0;
> +
> + Status = HiiStringToOneOfOptionValue (TargetStatement, Schema,
> TempBuffer, 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 ==
> EFI_IFR_ORDERED_LIST_OP && StatementValue->Type ==
> 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 = AllocateZeroPool (TargetStatement->HiiStatement-
> >StorageWidth);
> + if (StringArray == NULL) {
> + return EFI_OUT_OF_RESOURCES;
> + }
> +
> + //
> + // Arrage new option order from input string array
> + //
> + CharArray = (CHAR8 **)StatementValue->Buffer;
> + for (Index = 0; Index < StatementValue->BufferLen; Index++) {
> + TempBuffer = StrToUnicodeStr (CharArray[Index]);
> + if (TempBuffer == NULL) {
> + return EFI_OUT_OF_RESOURCES;
> + }
> +
> + Status = HiiStringToOrderedListOptionValue (TargetStatement, Schema,
> TempBuffer, &Value);
> + if (EFI_ERROR (Status)) {
> + ASSERT (FALSE);
> + continue;
> + }
> + FreePool (TempBuffer);
> + OrderedListSetArrayData (StringArray, TargetStatement->HiiStatement-
> >Value.BufferValueType, Index, Value);
> + }
> +
> + StatementValue->Type = EFI_IFR_TYPE_BUFFER;
> + StatementValue->Buffer = StringArray;
> + StatementValue->BufferLen = TargetStatement->HiiStatement-
> >StorageWidth;
> + StatementValue->BufferValueType = TargetStatement->HiiStatement-
> >Value.BufferValueType;
> + } else if (TargetStatement->HiiStatement->Operand ==
> EFI_IFR_NUMERIC_OP && StatementValue->Type ==
> EFI_IFR_TYPE_NUM_SIZE_64) {
> + //
> + // Redfish only has numeric value type and it does not care about the
> value size.
> + // Do a patch here so we have proper value size applied.
> + //
> + StatementValue->Type = 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, TargetStatement->HiiStatement->Value.Type));
> + ASSERT (FALSE);
> + }
> + }
> +
> + Status = 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",
> __FUNCTION__, Status));
> + return Status;
> + }
> +
> + return EFI_SUCCESS;
> +}
> +
> +/**
> + Set Redfish value with the given Schema and Configure Language.
> +
> + @param[in] This Pointer to
> EDKII_REDFISH_PLATFORM_CONFIG_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 configure
> 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 == NULL || IS_EMPTY_STRING (Schema) || IS_EMPTY_STRING
> (Version) || IS_EMPTY_STRING (ConfigureLang)) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + if (Value.Type == REDFISH_VALUE_TYPE_UNKNOWN || Value.Type >=
> REDFISH_VALUE_TYPE_MAX) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + RedfishPlatformConfigPrivate =
> REDFISH_PLATFORM_CONFIG_PRIVATE_FROM_THIS (This);
> + FullSchema = NULL;
> +
> + FullSchema = GetFullSchemaString (Schema, Version);
> + if (FullSchema == 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 = RedfishNumericToHiiValue (&Value, &NewValue);
> + if (EFI_ERROR (Status)) {
> + DEBUG ((DEBUG_ERROR, "%a, failed to convert Redfish value to Hii
> value: %r\n", __FUNCTION__, Status));
> + goto RELEASE_RESOURCE;
> + }
> + break;
> + case REDFISH_VALUE_TYPE_STRING:
> + NewValue.Type = EFI_IFR_TYPE_STRING;
> + NewValue.BufferLen = (UINT16)AsciiStrSize (Value.Value.Buffer);
> + NewValue.Buffer = AllocateCopyPool (NewValue.BufferLen,
> Value.Value.Buffer);
> + if (NewValue.Buffer == NULL) {
> + Status = EFI_OUT_OF_RESOURCES;
> + goto RELEASE_RESOURCE;
> + }
> + break;
> + case REDFISH_VALUE_TYPE_STRING_ARRAY:
> + NewValue.Type = EFI_IFR_TYPE_STRING;
> + NewValue.BufferLen = (UINT16)Value.ArrayCount;
> + NewValue.Buffer = (UINT8 *)Value.Value.StringArray;
> + break;
> + default:
> + ASSERT (FALSE);
> + break;
> + }
> +
> + Status = RedfishPlatformConfigSetStatementCommon
> (RedfishPlatformConfigPrivate, FullSchema, ConfigureLang, &NewValue);
> + if (EFI_ERROR (Status)) {
> + DEBUG ((DEBUG_ERROR, "%a, failed to set value to statement: %r\n",
> __FUNCTION__, Status));
> + }
> +
> +RELEASE_RESOURCE:
> +
> + if (FullSchema != NULL) {
> + FreePool (FullSchema);
> + }
> +
> + return Status;
> +}
> +
> +/**
> + Get the list of Configure Language from platform configuration by the
> given Schema and RegexPattern.
> +
> + @param[in] This Pointer to
> EDKII_REDFISH_PLATFORM_CONFIG_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
> ConfigureLangList.
> +
> + @retval EFI_SUCCESS ConfigureLangList is returned successfully.
> + @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
> *RedfishPlatformConfigPrivate;
> + 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 == NULL || IS_EMPTY_STRING (Schema) || IS_EMPTY_STRING
> (Version) || Count == NULL || ConfigureLangList == NULL ||
> IS_EMPTY_STRING (RegexPattern)) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + *Count = 0;
> + *ConfigureLangList = NULL;
> + FullSchema = NULL;
> + RedfishPlatformConfigPrivate =
> REDFISH_PLATFORM_CONFIG_PRIVATE_FROM_THIS (This);
> +
> + Status = ProcessPendingList (&RedfishPlatformConfigPrivate->FormsetList,
> &RedfishPlatformConfigPrivate->PendingList);
> + if (EFI_ERROR (Status)) {
> + DEBUG ((DEBUG_ERROR, "%a, ProcessPendingList failure: %r\n",
> __FUNCTION__, Status));
> + return Status;
> + }
> +
> + FullSchema = GetFullSchemaString (Schema, Version);
> + if (FullSchema == NULL) {
> + return EFI_OUT_OF_RESOURCES;
> + }
> +
> + Status = GetStatementPrivateByConfigureLangRegex (
> + RedfishPlatformConfigPrivate->RegularExpressionProtocol,
> + &RedfishPlatformConfigPrivate->FormsetList,
> + FullSchema,
> + RegexPattern,
> + &StatementList
> + );
> + if (EFI_ERROR (Status)) {
> + DEBUG ((DEBUG_ERROR, "%a,
> GetStatementPrivateByConfigureLangRegex failure: %r\n", __FUNCTION__,
> Status));
> + goto RELEASE_RESOURCE;
> + }
> +
> + if (!IsListEmpty (&StatementList.StatementList)) {
> +
> + TmpConfigureLangList = AllocateZeroPool (sizeof (CHAR16 *) *
> StatementList.Count);
> + if (TmpConfigureLangList == NULL) {
> + Status = EFI_OUT_OF_RESOURCES;
> + goto RELEASE_RESOURCE;
> + }
> +
> + Index = 0;
> + NextLink = GetFirstNode (&StatementList.StatementList);
> + while (!IsNull (&StatementList.StatementList, NextLink)) {
> + StatementRef =
> REDFISH_PLATFORM_CONFIG_STATEMENT_REF_FROM_LINK (NextLink);
> + NextLink = GetNextNode (&StatementList.StatementList, NextLink);
> +
> + ASSERT (StatementRef->Statement->Description != 0);
> + if (StatementRef->Statement->Description != 0) {
> + TmpString = HiiGetRedfishString (StatementRef->Statement-
> >ParentForm->ParentFormset->HiiHandle, FullSchema, StatementRef-
> >Statement->Description);
> + ASSERT (TmpString != NULL);
> + if (TmpString != NULL) {
> + TmpConfigureLangList[Index] = AllocateCopyPool (StrSize (TmpString),
> TmpString);
> + ASSERT (TmpConfigureLangList[Index] != NULL);
> + FreePool (TmpString);
> + ++Index;
> + }
> + }
> + }
> + }
> +
> + *Count = StatementList.Count;
> + *ConfigureLangList = TmpConfigureLangList;
> +
> +RELEASE_RESOURCE:
> +
> + if (FullSchema != 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_CONFIG_PROTOCOL instance.
> + @param[in] HiiHandle The target handle to search. If handle is NULL,
> + this function return all schema from HII database.
> + @param[out] SupportedSchema The supported schema list which is
> separated by ';'.
> + The SupportedSchema is allocated by the callee. It's
> caller's
> + responsibility to free this buffer using 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 == NULL || SupportedSchema == NULL) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + *SupportedSchema = NULL;
> +
> + RedfishPlatformConfigPrivate =
> REDFISH_PLATFORM_CONFIG_PRIVATE_FROM_THIS (This);
> +
> + Status = ProcessPendingList (&RedfishPlatformConfigPrivate->FormsetList,
> &RedfishPlatformConfigPrivate->PendingList);
> + if (EFI_ERROR (Status)) {
> + DEBUG ((DEBUG_ERROR, "%a, ProcessPendingList failure: %r\n",
> __FUNCTION__, Status));
> + return Status;
> + }
> +
> + if (IsListEmpty (&RedfishPlatformConfigPrivate->FormsetList)) {
> + return EFI_NOT_FOUND;
> + }
> +
> + //
> + // Calculate for string buffer size.
> + //
> + StringSize = 0;
> + HiiFormsetLink = GetFirstNode (&RedfishPlatformConfigPrivate-
> >FormsetList);
> + while (!IsNull (&RedfishPlatformConfigPrivate->FormsetList,
> HiiFormsetLink)) {
> + HiiFormsetNextLink = GetNextNode (&RedfishPlatformConfigPrivate-
> >FormsetList, HiiFormsetLink);
> + HiiFormsetPrivate =
> REDFISH_PLATFORM_CONFIG_FORMSET_FROM_LINK (HiiFormsetLink);
> +
> + if (HiiHandle != NULL && HiiHandle != HiiFormsetPrivate->HiiHandle) {
> + HiiFormsetLink = HiiFormsetNextLink;
> + continue;
> + }
> +
> + if (HiiFormsetPrivate->SupportedSchema.Count > 0) {
> + for (Index = 0; Index < HiiFormsetPrivate->SupportedSchema.Count;
> Index++) {
> + StringSize += AsciiStrSize (HiiFormsetPrivate-
> >SupportedSchema.SchemaList[Index]);
> + }
> + }
> +
> + HiiFormsetLink = HiiFormsetNextLink;
> + }
> +
> + if (StringSize == 0) {
> + return EFI_NOT_FOUND;
> + }
> +
> + StringBuffer = AllocatePool (StringSize);
> + if (StringBuffer == NULL) {
> + return EFI_OUT_OF_RESOURCES;
> + }
> +
> + StringIndex = 0;
> + HiiFormsetLink = GetFirstNode (&RedfishPlatformConfigPrivate-
> >FormsetList);
> + while (!IsNull (&RedfishPlatformConfigPrivate->FormsetList,
> HiiFormsetLink)) {
> + HiiFormsetNextLink = GetNextNode (&RedfishPlatformConfigPrivate-
> >FormsetList, HiiFormsetLink);
> + HiiFormsetPrivate =
> REDFISH_PLATFORM_CONFIG_FORMSET_FROM_LINK (HiiFormsetLink);
> +
> + if (HiiHandle != NULL && HiiHandle != HiiFormsetPrivate->HiiHandle) {
> + HiiFormsetLink = HiiFormsetNextLink;
> + continue;
> + }
> +
> + if (HiiFormsetPrivate->SupportedSchema.Count > 0) {
> + for (Index = 0; Index < HiiFormsetPrivate->SupportedSchema.Count;
> Index++) {
> + AsciiStrCpyS (&StringBuffer[StringIndex], (StringSize - StringIndex),
> HiiFormsetPrivate->SupportedSchema.SchemaList[Index]);
> + StringIndex += AsciiStrLen (HiiFormsetPrivate-
> >SupportedSchema.SchemaList[Index]);
> + StringBuffer[StringIndex] = ';';
> + ++StringIndex;
> + }
> + }
> +
> + HiiFormsetLink = HiiFormsetNextLink;
> + }
> +
> + StringBuffer[--StringIndex] = '\0';
> +
> + *SupportedSchema = 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 == EFI_HII_DATABASE_NOTIFY_NEW_PACK || NotifyType
> == EFI_HII_DATABASE_NOTIFY_ADD_PACK) {
> + //
> + // HII formset on this handle is updated by driver during run-time. The
> formset needs to be reloaded.
> + //
> + Status = NotifyFormsetUpdate (Handle,
> &mRedfishPlatformConfigPrivate->PendingList);
> + if (EFI_ERROR (Status)) {
> + DEBUG ((DEBUG_ERROR, "%a, failed to notify updated formset of HII
> handle: 0x%x\n", __FUNCTION__, Handle));
> + return Status;
> + }
> + } else if (NotifyType == EFI_HII_DATABASE_NOTIFY_REMOVE_PACK) {
> + //
> + // HII resource is removed. The formset is no longer exist.
> + //
> + Status = NotifyFormsetDeleted (Handle,
> &mRedfishPlatformConfigPrivate->PendingList);
> + if (EFI_ERROR (Status)) {
> + DEBUG ((DEBUG_ERROR, "%a, failed to notify deleted formset of HII
> handle: 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 = 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 = 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 = 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 = mRedfishPlatformConfigPrivate->HiiDatabase-
> >RegisterPackageNotify (
> + mRedfishPlatformConfigPrivate->HiiDatabase,
> + EFI_HII_PACKAGE_FORMS,
> + NULL,
> + RedfishPlatformConfigFormUpdateNotify,
> + EFI_HII_DATABASE_NOTIFY_NEW_PACK,
> + &mRedfishPlatformConfigPrivate->NotifyHandle
> + );
> + if (EFI_ERROR (Status)) {
> + DEBUG ((DEBUG_ERROR, "%a, RegisterPackageNotify for
> EFI_HII_DATABASE_NOTIFY_NEW_PACK failure: %r\n", __FUNCTION__,
> Status));
> + }
> +
> + //
> + // Register package notification when new form package is updated.
> + //
> + Status = mRedfishPlatformConfigPrivate->HiiDatabase-
> >RegisterPackageNotify (
> + mRedfishPlatformConfigPrivate->HiiDatabase,
> + EFI_HII_PACKAGE_FORMS,
> + NULL,
> + RedfishPlatformConfigFormUpdateNotify,
> + EFI_HII_DATABASE_NOTIFY_ADD_PACK,
> + &mRedfishPlatformConfigPrivate->NotifyHandle
> + );
> + if (EFI_ERROR (Status)) {
> + DEBUG ((DEBUG_ERROR, "%a, RegisterPackageNotify for
> EFI_HII_DATABASE_NOTIFY_NEW_PACK failure: %r\n", __FUNCTION__,
> Status));
> + }
> +
> + gBS->CloseEvent (Event);
> + mRedfishPlatformConfigPrivate->HiiDbNotify.ProtocolEvent = 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 = gBS->LocateProtocol (
> + &gEfiRegularExpressionProtocolGuid,
> + NULL,
> + (VOID **)&mRedfishPlatformConfigPrivate-
> >RegularExpressionProtocol
> + );
> + if (EFI_ERROR (Status)) {
> + DEBUG ((DEBUG_ERROR, "%a, locate
> EFI_REGULAR_EXPRESSION_PROTOCOL failure: %r\n", __FUNCTION__,
> Status));
> + return;
> + }
> +
> + gBS->CloseEvent (Event);
> + mRedfishPlatformConfigPrivate->RegexNotify.ProtocolEvent = NULL;
> +
> +}
> +
> +/**
> + Unloads an image.
> +
> + @param ImageHandle Handle that identifies the image to be
> unloaded.
> +
> + @retval EFI_SUCCESS The image has been unloaded.
> + @retval EFI_INVALID_PARAMETER ImageHandle is not a valid image
> handle.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +RedfishPlatformConfigDxeUnload (
> + IN EFI_HANDLE ImageHandle
> + )
> +{
> + EFI_STATUS Status;
> +
> + if (mRedfishPlatformConfigPrivate != NULL) {
> + Status = gBS->UninstallProtocolInterface (
> + mRedfishPlatformConfigPrivate->ImageHandle,
> + &gEdkIIRedfishPlatformConfigProtocolGuid,
> + (VOID*)&mRedfishPlatformConfigPrivate->Protocol
> + );
> + if (EFI_ERROR (Status)) {
> + DEBUG ((DEBUG_ERROR, "%a, can not uninstall
> gEdkIIRedfishPlatformConfigProtocolGuid: %r\n", __FUNCTION__, Status));
> + ASSERT (FALSE);
> + }
> +
> + //
> + // Close events
> + //
> + if (mRedfishPlatformConfigPrivate->HiiDbNotify.ProtocolEvent != NULL) {
> + gBS->CloseEvent (mRedfishPlatformConfigPrivate-
> >HiiDbNotify.ProtocolEvent);
> + }
> + if (mRedfishPlatformConfigPrivate->HiiStringNotify.ProtocolEvent !=
> NULL) {
> + gBS->CloseEvent (mRedfishPlatformConfigPrivate-
> >HiiStringNotify.ProtocolEvent);
> + }
> + if (mRedfishPlatformConfigPrivate->RegexNotify.ProtocolEvent != NULL)
> {
> + gBS->CloseEvent (mRedfishPlatformConfigPrivate-
> >RegexNotify.ProtocolEvent);
> + }
> +
> + //
> + // Unregister package notification.
> + //
> + if (mRedfishPlatformConfigPrivate->NotifyHandle != NULL) {
> + mRedfishPlatformConfigPrivate->HiiDatabase->UnregisterPackageNotify
> (
> + mRedfishPlatformConfigPrivate->HiiDatabase,
> + mRedfishPlatformConfigPrivate->NotifyHandle
> + );
> + }
> +
> + ReleaseFormsetList (&mRedfishPlatformConfigPrivate->FormsetList);
> + FreePool (mRedfishPlatformConfigPrivate);
> + mRedfishPlatformConfigPrivate = 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 including
> + 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 = (REDFISH_PLATFORM_CONFIG_PRIVATE
> *)AllocateZeroPool (sizeof (REDFISH_PLATFORM_CONFIG_PRIVATE));
> + if (mRedfishPlatformConfigPrivate == NULL) {
> + DEBUG ((DEBUG_ERROR, "%a, can not allocate pool for
> REDFISH_PLATFORM_CONFIG_PRIVATE\n", __FUNCTION__));
> + ASSERT (FALSE);
> + return EFI_OUT_OF_RESOURCES;
> + }
> +
> + //
> + // Protocol initialization
> + //
> + mRedfishPlatformConfigPrivate->ImageHandle = ImageHandle;
> + mRedfishPlatformConfigPrivate->Protocol.GetValue =
> RedfishPlatformConfigProtocolGetValue;
> + mRedfishPlatformConfigPrivate->Protocol.SetValue =
> RedfishPlatformConfigProtocolSetValue;
> + mRedfishPlatformConfigPrivate->Protocol.GetConfigureLang =
> RedfishPlatformConfigProtocolGetConfigureLang;
> + mRedfishPlatformConfigPrivate->Protocol.GetSupportedSchema =
> RedfishPlatformConfigProtocolGetSupportedSchema;
> +
> + InitializeListHead (&mRedfishPlatformConfigPrivate->FormsetList);
> + InitializeListHead (&mRedfishPlatformConfigPrivate->PendingList);
> +
> + Status = gBS->InstallProtocolInterface (
> + &ImageHandle,
> + &gEdkIIRedfishPlatformConfigProtocolGuid,
> + EFI_NATIVE_INTERFACE,
> + (VOID*)&mRedfishPlatformConfigPrivate->Protocol
> + );
> + if (EFI_ERROR (Status)) {
> + DEBUG ((DEBUG_ERROR, "%a, can not install
> gEdkIIRedfishPlatformConfigProtocolGuid: %r\n", __FUNCTION__, Status));
> + ASSERT (FALSE);
> + }
> +
> + //
> + // Install protocol notification if HII database protocol is installed.
> + //
> + mRedfishPlatformConfigPrivate->HiiDbNotify.ProtocolEvent =
> EfiCreateProtocolNotifyEvent (
> + &gEfiHiiDatabaseProtocolGuid,
> + TPL_CALLBACK,
> + HiiDatabaseProtocolInstalled,
> + NULL,
> + &mRedfishPlatformConfigPrivate-
> >HiiDbNotify.Registration
> + );
> + if (mRedfishPlatformConfigPrivate->HiiDbNotify.ProtocolEvent == NULL) {
> + DEBUG ((DEBUG_ERROR, "%a, failed to create protocol notification for
> gEfiHiiDatabaseProtocolGuid\n", __FUNCTION__));
> + ASSERT (FALSE);
> + }
> +
> + //
> + // Install protocol notification if HII string protocol is installed.
> + //
> + mRedfishPlatformConfigPrivate->HiiStringNotify.ProtocolEvent =
> EfiCreateProtocolNotifyEvent (
> + &gEfiHiiStringProtocolGuid,
> + TPL_CALLBACK,
> + HiiStringProtocolInstalled,
> + NULL,
> + &mRedfishPlatformConfigPrivate-
> >HiiStringNotify.Registration
> + );
> + if (mRedfishPlatformConfigPrivate->HiiStringNotify.ProtocolEvent == NULL)
> {
> + DEBUG ((DEBUG_ERROR, "%a, failed to create protocol notification for
> gEfiHiiStringProtocolGuid\n", __FUNCTION__));
> + ASSERT (FALSE);
> + }
> +
> + //
> + // Install protocol notification if regular expression protocol is installed.
> + //
> + mRedfishPlatformConfigPrivate->RegexNotify.ProtocolEvent =
> EfiCreateProtocolNotifyEvent (
> + &gEfiRegularExpressionProtocolGuid,
> + TPL_CALLBACK,
> + RegexProtocolInstalled,
> + NULL,
> + &mRedfishPlatformConfigPrivate-
> >RegexNotify.Registration
> + );
> + if (mRedfishPlatformConfigPrivate->RegexNotify.ProtocolEvent == NULL) {
> + DEBUG ((DEBUG_ERROR, "%a, failed to create protocol notification for
> gEfiRegularExpressionProtocolGuid\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<BR>
> -
> - SPDX-License-Identifier: BSD-2-Clause-Patent
> -
> -**/
> -
> -#ifndef EDKII_REDFISH_PLATFORM_CONFIG_DXE_H_
> -#define EDKII_REDFISH_PLATFORM_CONFIG_DXE_H_
> -
> -#include <Uefi.h>
> -
> -//
> -// Libraries
> -//
> -#include <Library/BaseLib.h>
> -#include <Library/BaseMemoryLib.h>
> -#include <Library/DebugLib.h>
> -#include <Library/MemoryAllocationLib.h>
> -#include <Library/PrintLib.h>
> -#include <Library/UefiLib.h>
> -#include <Library/UefiBootServicesTableLib.h>
> -#include <Library/UefiDriverEntryPoint.h>
> -
> -//
> -// Produced Protocols
> -//
> -#include <Protocol/EdkIIRedfishPlatformConfig.h>
> -#include <Protocol/HiiDatabase.h>
> -#include <Protocol/HiiString.h>
> -#include <Protocol/RegularExpressionProtocol.h>
> -
> -//
> -// Definition of EDKII_REDFISH_PLATFORM_CONFIG_NOTIFY.
> -//
> -typedef struct {
> - EFI_EVENT ProtocolEvent; // Protocol notification event.
> - VOID *Registration; // Protocol notification registration.
> -} 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<BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef EDKII_REDFISH_PLATFORM_CONFIG_DXE_H_
> +#define EDKII_REDFISH_PLATFORM_CONFIG_DXE_H_
> +
> +#include <Uefi.h>
> +
> +//
> +// Libraries
> +//
> +#include <Library/BaseLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/PrintLib.h>
> +#include <Library/UefiLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/UefiDriverEntryPoint.h>
> +
> +//
> +// Produced Protocols
> +//
> +#include <Protocol/EdkIIRedfishPlatformConfig.h>
> +#include <Protocol/HiiDatabase.h>
> +#include <Protocol/HiiString.h>
> +#include <Protocol/RegularExpressionProtocol.h>
> +
> +//
> +// Definition of EDKII_REDFISH_PLATFORM_CONFIG_NOTIFY.
> +//
> +typedef struct {
> + EFI_EVENT ProtocolEvent; // Protocol notification event.
> + VOID *Registration; // Protocol notification registration.
> +} 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.inf
> 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<BR>
> -# SPDX-License-Identifier: BSD-2-Clause-Patent
> -#
> -##
> -
> -[Defines]
> - INF_VERSION = 0x00010005
> - BASE_NAME = RedfishPlatformConfigDxe
> - FILE_GUID = BEAEFFE1-0633-41B5-913C-9389339C2927
> - MODULE_TYPE = DXE_DRIVER
> - VERSION_STRING = 1.0
> - ENTRY_POINT = RedfishPlatformConfigDxeEntryPoint
> - UNLOAD_IMAGE = 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<BR>
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> + INF_VERSION = 0x00010005
> + BASE_NAME = RedfishPlatformConfigDxe
> + FILE_GUID = BEAEFFE1-0633-41B5-913C-9389339C2927
> + MODULE_TYPE = DXE_DRIVER
> + VERSION_STRING = 1.0
> + ENTRY_POINT = RedfishPlatformConfigDxeEntryPoint
> + UNLOAD_IMAGE = 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..917f946656 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<BR>
> -
> - 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 == NULL || StringId == 0) {
> - DEBUG ((DEBUG_INFO, "???"));
> - return EFI_INVALID_PARAMETER;
> - }
> -
> - String = HiiGetString (HiiHandle, StringId, NULL);
> - if (String == 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 == NULL) {
> - return EFI_INVALID_PARAMETER;
> - }
> -
> - Index = 0;
> - HiiFormLink = GetFirstNode (&FormsetPrivate->HiiFormList);
> - while (!IsNull (&FormsetPrivate->HiiFormList, HiiFormLink)) {
> - HiiFormPrivate = REDFISH_PLATFORM_CONFIG_FORM_FROM_LINK
> (HiiFormLink);
> - HiiNextFormLink = GetNextNode (&FormsetPrivate->HiiFormList,
> HiiFormLink);
> -
> - DEBUG ((DEBUG_INFO, " [%d] form: %d title: ", ++Index, HiiFormPrivate-
> >Id));
> - DumpHiiString (FormsetPrivate->HiiHandle, HiiFormPrivate->Title);
> - DEBUG ((DEBUG_INFO, "\n"));
> -
> - HiiStatementLink = GetFirstNode (&HiiFormPrivate->StatementList);
> - while (!IsNull (&HiiFormPrivate->StatementList, HiiStatementLink)) {
> - HiiStatementPrivate =
> REDFISH_PLATFORM_CONFIG_STATEMENT_FROM_LINK (HiiStatementLink);
> - HiiNextStatementLink = GetNextNode (&HiiFormPrivate->StatementList,
> HiiStatementLink);
> -
> - DEBUG ((DEBUG_INFO, " QID: 0x%x Prompt: ", HiiStatementPrivate-
> >QuestionId));
> - DumpHiiString (FormsetPrivate->HiiHandle, HiiStatementPrivate-
> >Description);
> - DEBUG ((DEBUG_INFO, "\n"));
> -
> - HiiStatementLink = HiiNextStatementLink;
> - }
> -
> - HiiFormLink = 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 == NULL) {
> - return EFI_INVALID_PARAMETER;
> - }
> -
> - if (IsListEmpty (FormsetList)) {
> - DEBUG ((DEBUG_INFO, "%a, Empty formset list\n", __FUNCTION__));
> - return EFI_SUCCESS;
> - }
> -
> - Index = 0;
> - HiiFormsetLink = GetFirstNode (FormsetList);
> - while (!IsNull (FormsetList, HiiFormsetLink)) {
> - HiiFormsetNextLink = GetNextNode (FormsetList, HiiFormsetLink);
> - HiiFormsetPrivate =
> REDFISH_PLATFORM_CONFIG_FORMSET_FROM_LINK (HiiFormsetLink);
> -
> - DEBUG ((DEBUG_INFO, "[%d] HII Handle: 0x%x formset: %g at %s\n",
> ++Index, HiiFormsetPrivate->HiiHandle, &HiiFormsetPrivate->Guid,
> HiiFormsetPrivate->DevicePathStr));
> - DumpFormset (HiiFormsetPrivate);
> -
> - HiiFormsetLink = 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 responsible
> - 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 string
> 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 == NULL || HiiHandle == NULL
> || StringId == 0 || IS_EMPTY_STRING (Language)) {
> - ASSERT (FALSE);
> - return NULL;
> - }
> -
> - //
> - // Retrieve the size of the string in the string package for the BestLanguage
> - //
> - StringSize = 0;
> - Status = 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
> GetString()
> - // returns an error other than EFI_BUFFER_TOO_SMALL, then HiiHandle is
> not present
> - // in the HII Database
> - //
> - if (Status != EFI_BUFFER_TOO_SMALL) {
> - return NULL;
> - }
> -
> - //
> - // Allocate a buffer for the return string
> - //
> - String = AllocateZeroPool (StringSize);
> - if (String == NULL) {
> - return NULL;
> - }
> -
> - //
> - // Retrieve the string from the string package
> - //
> - Status = 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 = 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 string
> 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
> otherwise.
> -
> -**/
> -BOOLEAN
> -CheckSupportedSchema (
> - IN REDFISH_PLATFORM_CONFIG_SCHEMA *SupportedSchema,
> - IN CHAR8 *Schema
> - )
> -{
> - UINTN Index;
> -
> - if (SupportedSchema == NULL || IS_EMPTY_STRING (Schema)) {
> - return FALSE;
> - }
> -
> - if (SupportedSchema->Count == 0) {
> - return FALSE;
> - }
> -
> - for (Index = 0; Index < SupportedSchema->Count; Index++) {
> - if (AsciiStrCmp (SupportedSchema->SchemaList[Index], Schema) == 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 NULL.
> - @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 == NULL || SupportedSchema == NULL) {
> - return EFI_INVALID_PARAMETER;
> - }
> -
> - SupportedSchema->Count = 0;
> -
> - SupportedLanguages = HiiGetSupportedLanguages (HiiHandle);
> - if (SupportedLanguages == NULL) {
> - return EFI_NOT_FOUND;
> - }
> -
> - Index = 0;
> - LangIndex = 0;
> - Count = 0;
> - while (TRUE) {
> - if (SupportedLanguages[Index] == ';' || SupportedLanguages[Index] ==
> '\0') {
> - if (AsciiStrnCmp (&SupportedLanguages[LangIndex],
> X_UEFI_SCHEMA_PREFIX, AsciiStrLen (X_UEFI_SCHEMA_PREFIX)) == 0) {
> - ++Count;
> - }
> - LangIndex = Index + 1;
> - }
> -
> - if (SupportedLanguages[Index] == '\0') {
> - break;
> - }
> -
> - ++Index;
> - }
> -
> - if (Count == 0) {
> - return EFI_NOT_FOUND;
> - }
> -
> - SupportedSchema->Count = Count;
> - SupportedSchema->SchemaList = AllocatePool (sizeof (CHAR8 *) * Count);
> - if (SupportedSchema->SchemaList == NULL) {
> - return EFI_OUT_OF_RESOURCES;
> - }
> -
> - Index = 0;
> - LangIndex = 0;
> - ListIndex = 0;
> - while (TRUE) {
> -
> - if (SupportedLanguages[Index] == ';' || SupportedLanguages[Index] ==
> '\0') {
> - if (AsciiStrnCmp (&SupportedLanguages[LangIndex],
> X_UEFI_SCHEMA_PREFIX, AsciiStrLen (X_UEFI_SCHEMA_PREFIX)) == 0) {
> - StrSize = Index - LangIndex;
> - SupportedSchema->SchemaList[ListIndex] = AllocateCopyPool ((StrSize
> + 1), &SupportedLanguages[LangIndex]);
> - SupportedSchema->SchemaList[ListIndex][StrSize] = '\0';
> - ++ListIndex;
> - }
> -
> - LangIndex = Index + 1;
> - }
> -
> - if (SupportedLanguages[Index] == '\0') {
> - break;
> - }
> -
> - ++Index;
> - }
> -
> - return EFI_SUCCESS;
> -}
> -
> -/**
> - Search and find statement private instance by given regular expression
> patthern
> - 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
> *RegularExpressionProtocol,
> - 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 == NULL || IS_EMPTY_STRING (Schema) ||
> IS_EMPTY_STRING (Pattern) || StatementList == NULL) {
> - return EFI_INVALID_PARAMETER;
> - }
> -
> - if (RegularExpressionProtocol == NULL) {
> - return EFI_NOT_READY;
> - }
> -
> - StatementList->Count = 0;
> - InitializeListHead (&StatementList->StatementList);
> -
> - if (IsListEmpty (FormsetList)) {
> - return EFI_NOT_FOUND;
> - }
> -
> - HiiFormsetLink = GetFirstNode (FormsetList);
> - while (!IsNull (FormsetList, HiiFormsetLink)) {
> - HiiFormsetNextLink = GetNextNode (FormsetList, HiiFormsetLink);
> - HiiFormsetPrivate =
> REDFISH_PLATFORM_CONFIG_FORMSET_FROM_LINK (HiiFormsetLink);
> -
> - //
> - // Performance check.
> - // If there is no desired Redfish schema found, skip this formset.
> - //
> - if (!CheckSupportedSchema (&HiiFormsetPrivate->SupportedSchema,
> Schema)) {
> - HiiFormsetLink = HiiFormsetNextLink;
> - continue;
> - }
> -
> - HiiFormLink = GetFirstNode (&HiiFormsetPrivate->HiiFormList);
> - while (!IsNull (&HiiFormsetPrivate->HiiFormList, HiiFormLink)) {
> - HiiNextFormLink = GetNextNode (&HiiFormsetPrivate->HiiFormList,
> HiiFormLink);
> - HiiFormPrivate = REDFISH_PLATFORM_CONFIG_FORM_FROM_LINK
> (HiiFormLink);
> -
> - HiiStatementLink =GetFirstNode (&HiiFormPrivate->StatementList);
> - while (!IsNull (&HiiFormPrivate->StatementList, HiiStatementLink)) {
> - HiiNextStatementLink = GetNextNode (&HiiFormPrivate->StatementList,
> HiiStatementLink);
> - HiiStatementPrivate =
> REDFISH_PLATFORM_CONFIG_STATEMENT_FROM_LINK (HiiStatementLink);
> -
> - if (HiiStatementPrivate->Description != 0) {
> - TmpString = HiiGetRedfishString (HiiFormsetPrivate->HiiHandle,
> Schema, HiiStatementPrivate->Description);
> - if (TmpString != NULL) {
> - Status = RegularExpressionProtocol->MatchString (
> - RegularExpressionProtocol,
> - TmpString,
> - Pattern,
> - &gEfiRegexSyntaxTypePerlGuid,
> - &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 = AllocateZeroPool (sizeof
> (REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_REF));
> - if (StatementRef == NULL) {
> - return EFI_OUT_OF_RESOURCES;
> - }
> -
> - StatementRef->Statement = HiiStatementPrivate;
> - InsertTailList (&StatementList->StatementList, &StatementRef->Link);
> - ++StatementList->Count;
> - }
> -
> - FreePool (TmpString);
> - }
> - }
> -
> - HiiStatementLink = HiiNextStatementLink;
> - }
> -
> - HiiFormLink = HiiNextFormLink;
> - }
> -
> - HiiFormsetLink = 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
> statement 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 == NULL || IS_EMPTY_STRING (Schema) ||
> IS_EMPTY_STRING (ConfigureLang)) {
> - return NULL;
> - }
> -
> - if (IsListEmpty (FormsetList)) {
> - return NULL;
> - }
> -
> - HiiFormsetLink = GetFirstNode (FormsetList);
> - while (!IsNull (FormsetList, HiiFormsetLink)) {
> - HiiFormsetNextLink = GetNextNode (FormsetList, HiiFormsetLink);
> - HiiFormsetPrivate =
> REDFISH_PLATFORM_CONFIG_FORMSET_FROM_LINK (HiiFormsetLink);
> -
> - //
> - // Performance check.
> - // If there is no desired Redfish schema found, skip this formset.
> - //
> - if (!CheckSupportedSchema (&HiiFormsetPrivate->SupportedSchema,
> Schema)) {
> - HiiFormsetLink = HiiFormsetNextLink;
> - continue;
> - }
> -
> - HiiFormLink = GetFirstNode (&HiiFormsetPrivate->HiiFormList);
> - while (!IsNull (&HiiFormsetPrivate->HiiFormList, HiiFormLink)) {
> - HiiNextFormLink = GetNextNode (&HiiFormsetPrivate->HiiFormList,
> HiiFormLink);
> - HiiFormPrivate = REDFISH_PLATFORM_CONFIG_FORM_FROM_LINK
> (HiiFormLink);
> -
> - HiiStatementLink =GetFirstNode (&HiiFormPrivate->StatementList);
> - while (!IsNull (&HiiFormPrivate->StatementList, HiiStatementLink)) {
> - HiiNextStatementLink = GetNextNode (&HiiFormPrivate->StatementList,
> HiiStatementLink);
> - HiiStatementPrivate =
> REDFISH_PLATFORM_CONFIG_STATEMENT_FROM_LINK (HiiStatementLink);
> -
> - DEBUG_CODE (
> - STATIC UINTN Index = 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 != 0) {
> - TmpString = HiiGetRedfishString (HiiFormsetPrivate->HiiHandle,
> Schema, HiiStatementPrivate->Description);
> - if (TmpString != NULL) {
> - if (StrCmp (TmpString, ConfigureLang) == 0) {
> - FreePool (TmpString);
> - return HiiStatementPrivate;
> - }
> -
> - FreePool (TmpString);
> - }
> - }
> -
> - HiiStatementLink = HiiNextStatementLink;
> - }
> -
> - HiiFormLink = HiiNextFormLink;
> - }
> -
> - HiiFormsetLink = 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 == NULL || FormsetList == NULL) {
> - return NULL;
> - }
> -
> - if (IsListEmpty (FormsetList)) {
> - return NULL;
> - }
> -
> - HiiFormsetLink = GetFirstNode (FormsetList);
> - while (!IsNull (FormsetList, HiiFormsetLink)) {
> - HiiFormsetNextLink = GetNextNode (FormsetList, HiiFormsetLink);
> - HiiFormsetPrivate =
> REDFISH_PLATFORM_CONFIG_FORMSET_FROM_LINK (HiiFormsetLink);
> -
> - if (HiiFormsetPrivate->HiiHandle == HiiHandle) {
> - return HiiFormsetPrivate;
> - }
> -
> - HiiFormsetLink = HiiFormsetNextLink;
> - }
> -
> - return NULL;
> -}
> -
> -/**
> - Release formset and all the forms and statements that belong to this
> formset.
> -
> - @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 == NULL) {
> - return EFI_INVALID_PARAMETER;
> - }
> -
> - HiiFormLink = GetFirstNode (&FormsetPrivate->HiiFormList);
> - while (!IsNull (&FormsetPrivate->HiiFormList, HiiFormLink)) {
> - HiiFormPrivate = REDFISH_PLATFORM_CONFIG_FORM_FROM_LINK
> (HiiFormLink);
> - HiiNextFormLink = GetNextNode (&FormsetPrivate->HiiFormList,
> HiiFormLink);
> -
> - HiiStatementLink = GetFirstNode (&HiiFormPrivate->StatementList);
> - while (!IsNull (&HiiFormPrivate->StatementList, HiiStatementLink)) {
> - HiiStatementPrivate =
> REDFISH_PLATFORM_CONFIG_STATEMENT_FROM_LINK (HiiStatementLink);
> - HiiNextStatementLink = GetNextNode (&HiiFormPrivate->StatementList,
> HiiStatementLink);
> -
> - //
> - // HiiStatementPrivate->HiiStatement will be released in
> DestroyFormSet().
> - //
> -
> - if (HiiStatementPrivate->DesStringCache != NULL) {
> - FreePool (HiiStatementPrivate->DesStringCache);
> - HiiStatementPrivate->DesStringCache = NULL;
> - }
> -
> - RemoveEntryList (&HiiStatementPrivate->Link);
> - FreePool (HiiStatementPrivate);
> - HiiStatementLink = HiiNextStatementLink;
> - }
> -
> - //
> - // HiiStatementPrivate->HiiForm will be released in DestroyFormSet().
> - //
> -
> - RemoveEntryList (&HiiFormPrivate->Link);
> - FreePool (HiiFormPrivate);
> - HiiFormLink = HiiNextFormLink;
> - }
> -
> - if (FormsetPrivate->HiiFormSet != NULL) {
> - DestroyFormSet (FormsetPrivate->HiiFormSet);
> - FormsetPrivate->HiiFormSet = NULL;
> - }
> -
> - FreePool (FormsetPrivate->DevicePathStr);
> -
> - //
> - // Release schema list
> - //
> - if (FormsetPrivate->SupportedSchema.SchemaList != NULL) {
> - for (Index = 0; Index < FormsetPrivate->SupportedSchema.Count;
> Index++) {
> - FreePool (FormsetPrivate->SupportedSchema.SchemaList[Index]);
> - }
> -
> - FreePool (FormsetPrivate->SupportedSchema.SchemaList);
> - FormsetPrivate->SupportedSchema.SchemaList = NULL;
> - FormsetPrivate->SupportedSchema.Count = 0;
> - }
> -
> - return EFI_SUCCESS;
> -}
> -
> -/**
> - Create new form-set instance.
> -
> - @retval REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE * Pointer to
> newly created form-set private instance.
> -
> -**/
> -REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *
> -NewFormsetPrivate (
> - VOID
> - )
> -{
> - REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *NewFormsetPrivate;
> -
> - NewFormsetPrivate = AllocateZeroPool (sizeof
> (REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE));
> - if (NewFormsetPrivate == 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 == NULL || FormsetPrivate == NULL) {
> - return EFI_INVALID_PARAMETER;
> - }
> -
> -
> - HiiFormSet = AllocateZeroPool (sizeof (HII_FORMSET));
> - if (HiiFormSet == NULL) {
> - return EFI_OUT_OF_RESOURCES;
> - }
> -
> - //
> - // Find HII formset by the given HII handle.
> - //
> - ZeroMem (&ZeroGuid, sizeof (ZeroGuid));
> - Status = CreateFormSetFromHiiHandle (HiiHandle, &ZeroGuid, HiiFormSet);
> - if (EFI_ERROR (Status) || IsListEmpty (&HiiFormSet->FormListHead)) {
> - Status = EFI_NOT_FOUND;
> - goto ErrorExit;
> - }
> -
> - //
> - // Initialize formset
> - //
> - InitializeFormSet (HiiFormSet);
> -
> - //
> - // Initialize formset private data.
> - //
> - FormsetPrivate->HiiFormSet = HiiFormSet;
> - FormsetPrivate->HiiHandle = HiiHandle;
> - CopyGuid (&FormsetPrivate->Guid, &HiiFormSet->Guid);
> - FormsetPrivate->DevicePathStr = ConvertDevicePathToText (HiiFormSet-
> >DevicePath, FALSE, FALSE);
> - Status = GetSupportedSchema (FormsetPrivate->HiiHandle,
> &FormsetPrivate->SupportedSchema);
> - if (EFI_ERROR (Status)) {
> - DEBUG ((DEBUG_WARN, "%a, No schema from HII handle: 0x%x found:
> %r\n", __FUNCTION__, FormsetPrivate->HiiHandle, Status));
> - }
> -
> - HiiFormLink = GetFirstNode (&HiiFormSet->FormListHead);
> - while (!IsNull (&HiiFormSet->FormListHead, HiiFormLink)) {
> - HiiForm = HII_FORM_FROM_LINK (HiiFormLink);
> -
> - HiiFormPrivate = AllocateZeroPool (sizeof
> (REDFISH_PLATFORM_CONFIG_FORM_PRIVATE));
> - if (HiiFormPrivate == NULL) {
> - Status = EFI_OUT_OF_RESOURCES;
> - goto ErrorExit;
> - }
> -
> - //
> - // Initialize form private data.
> - //
> - HiiFormPrivate->HiiForm = HiiForm;
> - HiiFormPrivate->Id = HiiForm->FormId;
> - HiiFormPrivate->Title = HiiForm->FormTitle;
> - HiiFormPrivate->ParentFormset = FormsetPrivate;
> - InitializeListHead (&HiiFormPrivate->StatementList);
> -
> - HiiStatementLink = GetFirstNode (&HiiForm->StatementListHead);
> - while (!IsNull (&HiiForm->StatementListHead, HiiStatementLink)) {
> - HiiStatement = HII_STATEMENT_FROM_LINK (HiiStatementLink);
> -
> - HiiStatementPrivate = AllocateZeroPool (sizeof
> (REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE));
> - if (HiiStatementPrivate == NULL) {
> - Status = EFI_OUT_OF_RESOURCES;
> - goto ErrorExit;
> - }
> - //
> - // Initialize statement private data.
> - //
> - HiiStatementPrivate->HiiStatement = HiiStatement;
> - HiiStatementPrivate->QuestionId = HiiStatement->QuestionId;
> - HiiStatementPrivate->Description = HiiStatement->Prompt;
> - HiiStatementPrivate->ParentForm = HiiFormPrivate;
> -
> - //
> - // Attach to statement list.
> - //
> - InsertTailList (&HiiFormPrivate->StatementList, &HiiStatementPrivate-
> >Link);
> - HiiStatementLink = GetNextNode (&HiiForm->StatementListHead,
> HiiStatementLink);
> - }
> - //
> - // Attach to form list.
> - //
> - InsertTailList (&FormsetPrivate->HiiFormList, &HiiFormPrivate->Link);
> - HiiFormLink = GetNextNode (&HiiFormSet->FormListHead, HiiFormLink);
> - }
> -
> - return EFI_SUCCESS;
> -
> -ErrorExit:
> -
> - //
> - // Release HiiFormSet if HiiFormSet is not linked to FormsetPrivate yet.
> - //
> - if (HiiFormSet != NULL && FormsetPrivate->HiiFormSet != 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 == NULL || FormsetList == NULL) {
> - return EFI_INVALID_PARAMETER;
> - }
> -
> - FormsetPrivate = GetFormsetPrivateByHiiHandle (HiiHandle, FormsetList);
> - if (FormsetPrivate != NULL) {
> - return EFI_ALREADY_STARTED;
> - }
> -
> - FormsetPrivate = NewFormsetPrivate ();
> - if (FormsetPrivate == NULL) {
> - DEBUG ((DEBUG_ERROR, "%a, out of resource\n", __FUNCTION__));
> - return EFI_OUT_OF_RESOURCES;
> - }
> -
> - //
> - // Load formset on the given HII handle.
> - //
> - Status = 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 == NULL) {
> - return EFI_INVALID_PARAMETER;
> - }
> -
> - if (IsListEmpty (FormsetList)) {
> - return EFI_SUCCESS;
> - }
> -
> - HiiFormsetLink = GetFirstNode (FormsetList);
> - while (!IsNull (FormsetList, HiiFormsetLink)) {
> - HiiFormsetNextLink = GetNextNode (FormsetList, HiiFormsetLink);
> - HiiFormsetPrivate =
> REDFISH_PLATFORM_CONFIG_FORMSET_FROM_LINK (HiiFormsetLink);
> -
> - //
> - // Detach from list.
> - //
> - RemoveEntryList (&HiiFormsetPrivate->Link);
> - ReleaseFormset (HiiFormsetPrivate);
> - FreePool (HiiFormsetPrivate);
> - HiiFormsetLink = 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 == NULL || PendingList == NULL) {
> - return NULL;
> - }
> -
> - if (IsListEmpty (PendingList)) {
> - return NULL;
> - }
> -
> - PendingListLink = GetFirstNode (PendingList);
> - while (!IsNull (PendingList, PendingListLink)) {
> - Target = REDFISH_PLATFORM_CONFIG_PENDING_LIST_FROM_LINK
> (PendingListLink);
> -
> - if (Target->HiiHandle == HiiHandle) {
> - return Target;
> - }
> -
> - PendingListLink = 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 recently
> 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 == NULL || PendingList == NULL) {
> - return EFI_INVALID_PARAMETER;
> - }
> -
> - //
> - // Check and see if this HII handle is processed already.
> - //
> - TargetPendingList = GetPendingList (HiiHandle, PendingList);
> - if (TargetPendingList != NULL) {
> - TargetPendingList->IsDeleted = FALSE;
> - DEBUG_CODE (
> - DEBUG ((DEBUG_INFO, "%a, HII handle: 0x%x is updated\n",
> __FUNCTION__, HiiHandle));
> - );
> - return EFI_SUCCESS;
> - }
> -
> - TargetPendingList= AllocateZeroPool (sizeof
> (REDFISH_PLATFORM_CONFIG_PENDING_LIST));
> - if (TargetPendingList == NULL) {
> - return EFI_OUT_OF_RESOURCES;
> - }
> -
> - TargetPendingList->HiiHandle = HiiHandle;
> - TargetPendingList->IsDeleted = 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
> 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 recently
> 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 == NULL || PendingList == NULL) {
> - return EFI_INVALID_PARAMETER;
> - }
> -
> - //
> - // Check and see if this HII handle is processed already.
> - //
> - TargetPendingList = GetPendingList (HiiHandle, PendingList);
> - if (TargetPendingList != NULL) {
> - TargetPendingList->IsDeleted = TRUE;
> - DEBUG_CODE (
> - DEBUG ((DEBUG_INFO, "%a, HII handle: 0x%x is updated and deleted\n",
> __FUNCTION__, HiiHandle));
> - );
> - return EFI_SUCCESS;
> - }
> -
> - TargetPendingList= AllocateZeroPool (sizeof
> (REDFISH_PLATFORM_CONFIG_PENDING_LIST));
> - if (TargetPendingList == NULL) {
> - return EFI_OUT_OF_RESOURCES;
> - }
> -
> - TargetPendingList->HiiHandle = HiiHandle;
> - TargetPendingList->IsDeleted = 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
> NULL.
> -
> -**/
> -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 == NULL || PendingList == NULL) {
> - return EFI_INVALID_PARAMETER;
> - }
> -
> - if (IsListEmpty (PendingList)) {
> - return EFI_SUCCESS;
> - }
> -
> - PendingListLink = GetFirstNode (PendingList);
> - while (!IsNull (PendingList, PendingListLink)) {
> - PendingListNextLink = GetNextNode (PendingList, PendingListLink);
> - Target = REDFISH_PLATFORM_CONFIG_PENDING_LIST_FROM_LINK
> (PendingListLink);
> -
> - if (Target->IsDeleted) {
> - //
> - // The HII resource on this HII handle is removed. Release the formset.
> - //
> - FormsetPrivate = GetFormsetPrivateByHiiHandle (Target->HiiHandle,
> FormsetList);
> - if (FormsetPrivate != NULL) {
> - DEBUG ((DEBUG_INFO, "%a, formset: %g is removed because driver
> release 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
> already\n", __FUNCTION__, Target->HiiHandle));
> - }
> - } else {
> - //
> - // The HII resource on this HII handle is updated/removed.
> - //
> - FormsetPrivate = GetFormsetPrivateByHiiHandle (Target->HiiHandle,
> FormsetList);
> - if (FormsetPrivate != NULL) {
> - //
> - // HII formset already exist, release it and query again.
> - //
> - DEBUG ((DEBUG_INFO, "%a, formset: %g is updated. Release current
> formset\n", __FUNCTION__, &FormsetPrivate->Guid));
> - RemoveEntryList (&FormsetPrivate->Link);
> - ReleaseFormset (FormsetPrivate);
> - FreePool (FormsetPrivate);
> - }
> -
> - Status = LoadFormsetList (Target->HiiHandle, FormsetList);
> - if (EFI_ERROR (Status)) {
> - DEBUG ((DEBUG_ERROR, "%a, load formset from HII handle: 0x%x failed:
> %r\n", __FUNCTION__, Target->HiiHandle, Status));
> - }
> - }
> -
> - //
> - // Detach it from list first.
> - //
> - RemoveEntryList (&Target->Link);
> - FreePool (Target);
> -
> - PendingListLink = 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 == NULL) {
> - return EFI_INVALID_PARAMETER;
> - }
> -
> - if (IsListEmpty (&StatementList->StatementList)) {
> - return EFI_SUCCESS;
> - }
> -
> - NextLink = GetFirstNode (&StatementList->StatementList);
> - while (!IsNull (&StatementList->StatementList, NextLink)) {
> - StatementRef =
> REDFISH_PLATFORM_CONFIG_STATEMENT_REF_FROM_LINK (NextLink);
> - NextLink = 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<BR>
> +
> + 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 == NULL || StringId == 0) {
> + DEBUG ((DEBUG_INFO, "???"));
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + String = HiiGetString (HiiHandle, StringId, NULL);
> + if (String == 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 == NULL) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + Index = 0;
> + HiiFormLink = GetFirstNode (&FormsetPrivate->HiiFormList);
> + while (!IsNull (&FormsetPrivate->HiiFormList, HiiFormLink)) {
> + HiiFormPrivate = REDFISH_PLATFORM_CONFIG_FORM_FROM_LINK
> (HiiFormLink);
> + HiiNextFormLink = GetNextNode (&FormsetPrivate->HiiFormList,
> HiiFormLink);
> +
> + DEBUG ((DEBUG_INFO, " [%d] form: %d title: ", ++Index, HiiFormPrivate-
> >Id));
> + DumpHiiString (FormsetPrivate->HiiHandle, HiiFormPrivate->Title);
> + DEBUG ((DEBUG_INFO, "\n"));
> +
> + HiiStatementLink = GetFirstNode (&HiiFormPrivate->StatementList);
> + while (!IsNull (&HiiFormPrivate->StatementList, HiiStatementLink)) {
> + HiiStatementPrivate =
> REDFISH_PLATFORM_CONFIG_STATEMENT_FROM_LINK (HiiStatementLink);
> + HiiNextStatementLink = GetNextNode (&HiiFormPrivate->StatementList,
> HiiStatementLink);
> +
> + DEBUG ((DEBUG_INFO, " QID: 0x%x Prompt: ", HiiStatementPrivate-
> >QuestionId));
> + DumpHiiString (FormsetPrivate->HiiHandle, HiiStatementPrivate-
> >Description);
> + DEBUG ((DEBUG_INFO, "\n"));
> +
> + HiiStatementLink = HiiNextStatementLink;
> + }
> +
> + HiiFormLink = 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 == NULL) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + if (IsListEmpty (FormsetList)) {
> + DEBUG ((DEBUG_INFO, "%a, Empty formset list\n", __FUNCTION__));
> + return EFI_SUCCESS;
> + }
> +
> + Index = 0;
> + HiiFormsetLink = GetFirstNode (FormsetList);
> + while (!IsNull (FormsetList, HiiFormsetLink)) {
> + HiiFormsetNextLink = GetNextNode (FormsetList, HiiFormsetLink);
> + HiiFormsetPrivate =
> REDFISH_PLATFORM_CONFIG_FORMSET_FROM_LINK (HiiFormsetLink);
> +
> + DEBUG ((DEBUG_INFO, "[%d] HII Handle: 0x%x formset: %g at %s\n",
> ++Index, HiiFormsetPrivate->HiiHandle, &HiiFormsetPrivate->Guid,
> HiiFormsetPrivate->DevicePathStr));
> + DumpFormset (HiiFormsetPrivate);
> +
> + HiiFormsetLink = 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 responsible
> + 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 string
> 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 == NULL || HiiHandle ==
> NULL || StringId == 0 || IS_EMPTY_STRING (Language)) {
> + ASSERT (FALSE);
> + return NULL;
> + }
> +
> + //
> + // Retrieve the size of the string in the string package for the BestLanguage
> + //
> + StringSize = 0;
> + Status = 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
> GetString()
> + // returns an error other than EFI_BUFFER_TOO_SMALL, then HiiHandle is
> not present
> + // in the HII Database
> + //
> + if (Status != EFI_BUFFER_TOO_SMALL) {
> + return NULL;
> + }
> +
> + //
> + // Allocate a buffer for the return string
> + //
> + String = AllocateZeroPool (StringSize);
> + if (String == NULL) {
> + return NULL;
> + }
> +
> + //
> + // Retrieve the string from the string package
> + //
> + Status = 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 = NULL;
> + }
> +
> + //
> + // Return the Null-terminated Unicode string
> + //
> + return String;
> +}
> +
> +/**
> + Retrieves a string from a string package in a English language. The
> + returned string is allocated using AllocatePool(). The caller is responsible
> + 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
The function parameters are not correct.
> string
> + package associated with HiiHandle.
> +
> + @retval NULL The string specified by StringId is not present in the string
> 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 = HiiGetRedfishString (HiiHandle, Language, StringId);
> + if (HiiString == NULL) {
> + DEBUG ((DEBUG_ERROR, "%a, Can not find string ID: 0x%x with %a\n",
> __FUNCTION__, StringId, Language));
> + return NULL;
> + }
> +
> + StringSize = (StrLen (HiiString) + 1) * sizeof (CHAR8);
> + AsciiString = AllocatePool (StringSize);
> + if (AsciiString == 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 string
> 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
> otherwise.
> +
> +**/
> +BOOLEAN
> +CheckSupportedSchema (
> + IN REDFISH_PLATFORM_CONFIG_SCHEMA *SupportedSchema,
> + IN CHAR8 *Schema
> + )
> +{
> + UINTN Index;
> +
> + if (SupportedSchema == NULL || IS_EMPTY_STRING (Schema)) {
> + return FALSE;
> + }
> +
> + if (SupportedSchema->Count == 0) {
> + return FALSE;
> + }
> +
> + for (Index = 0; Index < SupportedSchema->Count; Index++) {
> + if (AsciiStrCmp (SupportedSchema->SchemaList[Index], Schema) == 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 NULL.
> + @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 == NULL || SupportedSchema == NULL) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + SupportedSchema->Count = 0;
> +
> + SupportedLanguages = HiiGetSupportedLanguages (HiiHandle);
> + if (SupportedLanguages == NULL) {
> + return EFI_NOT_FOUND;
> + }
> +
> + Index = 0;
> + LangIndex = 0;
> + Count = 0;
> + while (TRUE) {
> + if (SupportedLanguages[Index] == ';' || SupportedLanguages[Index] ==
> '\0') {
> + if (AsciiStrnCmp (&SupportedLanguages[LangIndex],
> X_UEFI_SCHEMA_PREFIX, AsciiStrLen (X_UEFI_SCHEMA_PREFIX)) == 0) {
> + ++Count;
> + }
> + LangIndex = Index + 1;
> + }
> +
> + if (SupportedLanguages[Index] == '\0') {
> + break;
> + }
> +
> + ++Index;
> + }
> +
> + if (Count == 0) {
> + return EFI_NOT_FOUND;
> + }
> +
> + SupportedSchema->Count = Count;
> + SupportedSchema->SchemaList = AllocatePool (sizeof (CHAR8 *) * Count);
> + if (SupportedSchema->SchemaList == NULL) {
> + return EFI_OUT_OF_RESOURCES;
> + }
> +
> + Index = 0;
> + LangIndex = 0;
> + ListIndex = 0;
> + while (TRUE) {
> +
> + if (SupportedLanguages[Index] == ';' || SupportedLanguages[Index] ==
> '\0') {
> + if (AsciiStrnCmp (&SupportedLanguages[LangIndex],
> X_UEFI_SCHEMA_PREFIX, AsciiStrLen (X_UEFI_SCHEMA_PREFIX)) == 0) {
> + StrSize = Index - LangIndex;
> + SupportedSchema->SchemaList[ListIndex] = AllocateCopyPool ((StrSize
> + 1), &SupportedLanguages[LangIndex]);
> + SupportedSchema->SchemaList[ListIndex][StrSize] = '\0';
> + ++ListIndex;
> + }
> +
> + LangIndex = Index + 1;
> + }
> +
> + if (SupportedLanguages[Index] == '\0') {
> + break;
> + }
> +
> + ++Index;
> + }
> +
> + return EFI_SUCCESS;
> +}
> +
> +/**
> + Search and find statement private instance by given regular expression
> patthern
> + 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
> *RegularExpressionProtocol,
> + 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 == NULL || IS_EMPTY_STRING (Schema) ||
> IS_EMPTY_STRING (Pattern) || StatementList == NULL) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + if (RegularExpressionProtocol == NULL) {
> + return EFI_NOT_READY;
> + }
> +
> + StatementList->Count = 0;
> + InitializeListHead (&StatementList->StatementList);
> +
> + if (IsListEmpty (FormsetList)) {
> + return EFI_NOT_FOUND;
> + }
> +
> + HiiFormsetLink = GetFirstNode (FormsetList);
> + while (!IsNull (FormsetList, HiiFormsetLink)) {
> + HiiFormsetNextLink = GetNextNode (FormsetList, HiiFormsetLink);
> + HiiFormsetPrivate =
> REDFISH_PLATFORM_CONFIG_FORMSET_FROM_LINK (HiiFormsetLink);
> +
> + //
> + // Performance check.
> + // If there is no desired Redfish schema found, skip this formset.
> + //
> + if (!CheckSupportedSchema (&HiiFormsetPrivate->SupportedSchema,
> Schema)) {
> + HiiFormsetLink = HiiFormsetNextLink;
> + continue;
> + }
> +
> + HiiFormLink = GetFirstNode (&HiiFormsetPrivate->HiiFormList);
> + while (!IsNull (&HiiFormsetPrivate->HiiFormList, HiiFormLink)) {
> + HiiNextFormLink = GetNextNode (&HiiFormsetPrivate->HiiFormList,
> HiiFormLink);
> + HiiFormPrivate = REDFISH_PLATFORM_CONFIG_FORM_FROM_LINK
> (HiiFormLink);
> +
> + HiiStatementLink =GetFirstNode (&HiiFormPrivate->StatementList);
> + while (!IsNull (&HiiFormPrivate->StatementList, HiiStatementLink)) {
> + HiiNextStatementLink = GetNextNode (&HiiFormPrivate-
> >StatementList, HiiStatementLink);
> + HiiStatementPrivate =
> REDFISH_PLATFORM_CONFIG_STATEMENT_FROM_LINK (HiiStatementLink);
> +
> + if (HiiStatementPrivate->Description != 0) {
> + TmpString = HiiGetRedfishString (HiiFormsetPrivate->HiiHandle,
> Schema, HiiStatementPrivate->Description);
> + if (TmpString != NULL) {
> + Status = RegularExpressionProtocol->MatchString (
> + RegularExpressionProtocol,
> + TmpString,
> + Pattern,
> + &gEfiRegexSyntaxTypePerlGuid,
> + &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 = AllocateZeroPool (sizeof
> (REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_REF));
> + if (StatementRef == NULL) {
> + return EFI_OUT_OF_RESOURCES;
> + }
> +
> + StatementRef->Statement = HiiStatementPrivate;
> + InsertTailList (&StatementList->StatementList, &StatementRef-
> >Link);
> + ++StatementList->Count;
> + }
> +
> + FreePool (TmpString);
> + }
> + }
> +
> + HiiStatementLink = HiiNextStatementLink;
> + }
> +
> + HiiFormLink = HiiNextFormLink;
> + }
> +
> + HiiFormsetLink = 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 statement 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 == NULL || IS_EMPTY_STRING (Schema) ||
> IS_EMPTY_STRING (ConfigureLang)) {
> + return NULL;
> + }
> +
> + if (IsListEmpty (FormsetList)) {
> + return NULL;
> + }
> +
> + HiiFormsetLink = GetFirstNode (FormsetList);
> + while (!IsNull (FormsetList, HiiFormsetLink)) {
> + HiiFormsetNextLink = GetNextNode (FormsetList, HiiFormsetLink);
> + HiiFormsetPrivate =
> REDFISH_PLATFORM_CONFIG_FORMSET_FROM_LINK (HiiFormsetLink);
> +
> + //
> + // Performance check.
> + // If there is no desired Redfish schema found, skip this formset.
> + //
> + if (!CheckSupportedSchema (&HiiFormsetPrivate->SupportedSchema,
> Schema)) {
> + HiiFormsetLink = HiiFormsetNextLink;
> + continue;
> + }
> +
> + HiiFormLink = GetFirstNode (&HiiFormsetPrivate->HiiFormList);
> + while (!IsNull (&HiiFormsetPrivate->HiiFormList, HiiFormLink)) {
> + HiiNextFormLink = GetNextNode (&HiiFormsetPrivate->HiiFormList,
> HiiFormLink);
> + HiiFormPrivate = REDFISH_PLATFORM_CONFIG_FORM_FROM_LINK
> (HiiFormLink);
> +
> + HiiStatementLink =GetFirstNode (&HiiFormPrivate->StatementList);
> + while (!IsNull (&HiiFormPrivate->StatementList, HiiStatementLink)) {
> + HiiNextStatementLink = GetNextNode (&HiiFormPrivate-
> >StatementList, HiiStatementLink);
> + HiiStatementPrivate =
> REDFISH_PLATFORM_CONFIG_STATEMENT_FROM_LINK (HiiStatementLink);
> +
> + DEBUG_CODE (
> + STATIC UINTN Index = 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 != 0) {
> + TmpString = HiiGetRedfishString (HiiFormsetPrivate->HiiHandle,
> Schema, HiiStatementPrivate->Description);
> + if (TmpString != NULL) {
> + if (StrCmp (TmpString, ConfigureLang) == 0) {
> + FreePool (TmpString);
> + return HiiStatementPrivate;
> + }
> +
> + FreePool (TmpString);
> + }
> + }
> +
> + HiiStatementLink = HiiNextStatementLink;
> + }
> +
> + HiiFormLink = HiiNextFormLink;
> + }
> +
> + HiiFormsetLink = 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 == NULL || FormsetList == NULL) {
> + return NULL;
> + }
> +
> + if (IsListEmpty (FormsetList)) {
> + return NULL;
> + }
> +
> + HiiFormsetLink = GetFirstNode (FormsetList);
> + while (!IsNull (FormsetList, HiiFormsetLink)) {
> + HiiFormsetNextLink = GetNextNode (FormsetList, HiiFormsetLink);
> + HiiFormsetPrivate =
> REDFISH_PLATFORM_CONFIG_FORMSET_FROM_LINK (HiiFormsetLink);
> +
> + if (HiiFormsetPrivate->HiiHandle == HiiHandle) {
> + return HiiFormsetPrivate;
> + }
> +
> + HiiFormsetLink = HiiFormsetNextLink;
> + }
> +
> + return NULL;
> +}
> +
> +/**
> + Release formset and all the forms and statements that belong to this
> formset.
> +
> + @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 == NULL) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + HiiFormLink = GetFirstNode (&FormsetPrivate->HiiFormList);
> + while (!IsNull (&FormsetPrivate->HiiFormList, HiiFormLink)) {
> + HiiFormPrivate = REDFISH_PLATFORM_CONFIG_FORM_FROM_LINK
> (HiiFormLink);
> + HiiNextFormLink = GetNextNode (&FormsetPrivate->HiiFormList,
> HiiFormLink);
> +
> + HiiStatementLink = GetFirstNode (&HiiFormPrivate->StatementList);
> + while (!IsNull (&HiiFormPrivate->StatementList, HiiStatementLink)) {
> + HiiStatementPrivate =
> REDFISH_PLATFORM_CONFIG_STATEMENT_FROM_LINK (HiiStatementLink);
> + HiiNextStatementLink = GetNextNode (&HiiFormPrivate->StatementList,
> HiiStatementLink);
> +
> + //
> + // HiiStatementPrivate->HiiStatement will be released in
> DestroyFormSet().
> + //
> +
> + if (HiiStatementPrivate->DesStringCache != NULL) {
> + FreePool (HiiStatementPrivate->DesStringCache);
> + HiiStatementPrivate->DesStringCache = NULL;
> + }
> +
> + RemoveEntryList (&HiiStatementPrivate->Link);
> + FreePool (HiiStatementPrivate);
> + HiiStatementLink = HiiNextStatementLink;
> + }
> +
> + //
> + // HiiStatementPrivate->HiiForm will be released in DestroyFormSet().
> + //
> +
> + RemoveEntryList (&HiiFormPrivate->Link);
> + FreePool (HiiFormPrivate);
> + HiiFormLink = HiiNextFormLink;
> + }
> +
> + if (FormsetPrivate->HiiFormSet != NULL) {
> + DestroyFormSet (FormsetPrivate->HiiFormSet);
> + FormsetPrivate->HiiFormSet = NULL;
> + }
> +
> + if (FormsetPrivate->DevicePathStr != NULL) {
> + FreePool(FormsetPrivate->DevicePathStr);
> + }
> +
> + //
> + // Release schema list
> + //
> + if (FormsetPrivate->SupportedSchema.SchemaList != NULL) {
> + for (Index = 0; Index < FormsetPrivate->SupportedSchema.Count;
> Index++) {
> + FreePool (FormsetPrivate->SupportedSchema.SchemaList[Index]);
> + }
> +
> + FreePool (FormsetPrivate->SupportedSchema.SchemaList);
> + FormsetPrivate->SupportedSchema.SchemaList = NULL;
> + FormsetPrivate->SupportedSchema.Count = 0;
> + }
> +
> + return EFI_SUCCESS;
> +}
> +
> +/**
> + Create new form-set instance.
> +
> + @retval REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE * Pointer to
> newly created form-set private instance.
> +
> +**/
> +REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *
> +NewFormsetPrivate (
> + VOID
> + )
> +{
> + REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *NewFormsetPrivate;
> +
> + NewFormsetPrivate = AllocateZeroPool (sizeof
> (REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE));
> + if (NewFormsetPrivate == 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 == NULL || FormsetPrivate == NULL) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> +
> + HiiFormSet = AllocateZeroPool (sizeof (HII_FORMSET));
> + if (HiiFormSet == NULL) {
> + return EFI_OUT_OF_RESOURCES;
> + }
> +
> + //
> + // Find HII formset by the given HII handle.
> + //
> + ZeroMem (&ZeroGuid, sizeof (ZeroGuid));
> + Status = CreateFormSetFromHiiHandle (HiiHandle, &ZeroGuid, HiiFormSet);
> + if (EFI_ERROR (Status) || IsListEmpty (&HiiFormSet->FormListHead)) {
> + Status = EFI_NOT_FOUND;
> + goto ErrorExit;
> + }
> +
> + //
> + // Initialize formset
> + //
> + InitializeFormSet (HiiFormSet);
> +
> + //
> + // Initialize formset private data.
> + //
> + FormsetPrivate->HiiFormSet = HiiFormSet;
> + FormsetPrivate->HiiHandle = HiiHandle;
> + CopyGuid (&FormsetPrivate->Guid, &HiiFormSet->Guid);
> + FormsetPrivate->DevicePathStr = ConvertDevicePathToText (HiiFormSet-
> >DevicePath, FALSE, FALSE);
> + Status = GetSupportedSchema (FormsetPrivate->HiiHandle,
> &FormsetPrivate->SupportedSchema);
> + if (EFI_ERROR (Status)) {
> + DEBUG ((DEBUG_WARN, "%a, No schema from HII handle: 0x%x found:
> %r\n", __FUNCTION__, FormsetPrivate->HiiHandle, Status));
> + }
> +
> + HiiFormLink = GetFirstNode (&HiiFormSet->FormListHead);
> + while (!IsNull (&HiiFormSet->FormListHead, HiiFormLink)) {
> + HiiForm = HII_FORM_FROM_LINK (HiiFormLink);
> +
> + HiiFormPrivate = AllocateZeroPool (sizeof
> (REDFISH_PLATFORM_CONFIG_FORM_PRIVATE));
> + if (HiiFormPrivate == NULL) {
> + Status = EFI_OUT_OF_RESOURCES;
> + goto ErrorExit;
> + }
> +
> + //
> + // Initialize form private data.
> + //
> + HiiFormPrivate->HiiForm = HiiForm;
> + HiiFormPrivate->Id = HiiForm->FormId;
> + HiiFormPrivate->Title = HiiForm->FormTitle;
> + HiiFormPrivate->ParentFormset = FormsetPrivate;
> + InitializeListHead (&HiiFormPrivate->StatementList);
> +
> + HiiStatementLink = GetFirstNode (&HiiForm->StatementListHead);
> + while (!IsNull (&HiiForm->StatementListHead, HiiStatementLink)) {
> + HiiStatement = HII_STATEMENT_FROM_LINK (HiiStatementLink);
> +
> + HiiStatementPrivate = AllocateZeroPool (sizeof
> (REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE));
> + if (HiiStatementPrivate == NULL) {
> + Status = EFI_OUT_OF_RESOURCES;
> + goto ErrorExit;
> + }
> + //
> + // Initialize statement private data.
> + //
> + HiiStatementPrivate->HiiStatement = HiiStatement;
> + HiiStatementPrivate->QuestionId = HiiStatement->QuestionId;
> + HiiStatementPrivate->Description = HiiStatement->Prompt;
> + HiiStatementPrivate->ParentForm = HiiFormPrivate;
> +
> + //
> + // Attach to statement list.
> + //
> + InsertTailList (&HiiFormPrivate->StatementList, &HiiStatementPrivate-
> >Link);
> + HiiStatementLink = GetNextNode (&HiiForm->StatementListHead,
> HiiStatementLink);
> + }
> + //
> + // Attach to form list.
> + //
> + InsertTailList (&FormsetPrivate->HiiFormList, &HiiFormPrivate->Link);
> + HiiFormLink = GetNextNode (&HiiFormSet->FormListHead, HiiFormLink);
> + }
> +
> + return EFI_SUCCESS;
> +
> +ErrorExit:
> +
> + //
> + // Release HiiFormSet if HiiFormSet is not linked to FormsetPrivate yet.
> + //
> + if (HiiFormSet != NULL && FormsetPrivate->HiiFormSet != 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 == NULL || FormsetList == NULL) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + FormsetPrivate = GetFormsetPrivateByHiiHandle (HiiHandle, FormsetList);
> + if (FormsetPrivate != NULL) {
> + return EFI_ALREADY_STARTED;
> + }
> +
> + FormsetPrivate = NewFormsetPrivate ();
> + if (FormsetPrivate == NULL) {
> + DEBUG ((DEBUG_ERROR, "%a, out of resource\n", __FUNCTION__));
> + return EFI_OUT_OF_RESOURCES;
> + }
> +
> + //
> + // Load formset on the given HII handle.
> + //
> + Status = 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 == NULL) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + if (IsListEmpty (FormsetList)) {
> + return EFI_SUCCESS;
> + }
> +
> + HiiFormsetLink = GetFirstNode (FormsetList);
> + while (!IsNull (FormsetList, HiiFormsetLink)) {
> + HiiFormsetNextLink = GetNextNode (FormsetList, HiiFormsetLink);
> + HiiFormsetPrivate =
> REDFISH_PLATFORM_CONFIG_FORMSET_FROM_LINK (HiiFormsetLink);
> +
> + //
> + // Detach from list.
> + //
> + RemoveEntryList (&HiiFormsetPrivate->Link);
> + ReleaseFormset (HiiFormsetPrivate);
> + FreePool (HiiFormsetPrivate);
> + HiiFormsetLink = 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 == NULL || PendingList == NULL) {
> + return NULL;
> + }
> +
> + if (IsListEmpty (PendingList)) {
> + return NULL;
> + }
> +
> + PendingListLink = GetFirstNode (PendingList);
> + while (!IsNull (PendingList, PendingListLink)) {
> + Target = REDFISH_PLATFORM_CONFIG_PENDING_LIST_FROM_LINK
> (PendingListLink);
> +
> + if (Target->HiiHandle == HiiHandle) {
> + return Target;
> + }
> +
> + PendingListLink = 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 recently
> 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 == NULL || PendingList == NULL) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + //
> + // Check and see if this HII handle is processed already.
> + //
> + TargetPendingList = GetPendingList (HiiHandle, PendingList);
> + if (TargetPendingList != NULL) {
> + TargetPendingList->IsDeleted = FALSE;
> + DEBUG_CODE (
> + DEBUG ((DEBUG_INFO, "%a, HII handle: 0x%x is updated\n",
> __FUNCTION__, HiiHandle));
> + );
> + return EFI_SUCCESS;
> + }
> +
> + TargetPendingList= AllocateZeroPool (sizeof
> (REDFISH_PLATFORM_CONFIG_PENDING_LIST));
> + if (TargetPendingList == NULL) {
> + return EFI_OUT_OF_RESOURCES;
> + }
> +
> + TargetPendingList->HiiHandle = HiiHandle;
> + TargetPendingList->IsDeleted = 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
> 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 recently
> 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 == NULL || PendingList == NULL) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + //
> + // Check and see if this HII handle is processed already.
> + //
> + TargetPendingList = GetPendingList (HiiHandle, PendingList);
> + if (TargetPendingList != NULL) {
> + TargetPendingList->IsDeleted = TRUE;
> + DEBUG_CODE (
> + DEBUG ((DEBUG_INFO, "%a, HII handle: 0x%x is updated and deleted\n",
> __FUNCTION__, HiiHandle));
> + );
> + return EFI_SUCCESS;
> + }
> +
> + TargetPendingList= AllocateZeroPool (sizeof
> (REDFISH_PLATFORM_CONFIG_PENDING_LIST));
> + if (TargetPendingList == NULL) {
> + return EFI_OUT_OF_RESOURCES;
> + }
> +
> + TargetPendingList->HiiHandle = HiiHandle;
> + TargetPendingList->IsDeleted = 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
> NULL.
> +
> +**/
> +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 == NULL || PendingList == NULL) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + if (IsListEmpty (PendingList)) {
> + return EFI_SUCCESS;
> + }
> +
> + PendingListLink = GetFirstNode (PendingList);
> + while (!IsNull (PendingList, PendingListLink)) {
> + PendingListNextLink = GetNextNode (PendingList, PendingListLink);
> + Target = REDFISH_PLATFORM_CONFIG_PENDING_LIST_FROM_LINK
> (PendingListLink);
> +
> + if (Target->IsDeleted) {
> + //
> + // The HII resource on this HII handle is removed. Release the formset.
> + //
> + FormsetPrivate = GetFormsetPrivateByHiiHandle (Target->HiiHandle,
> FormsetList);
> + if (FormsetPrivate != NULL) {
> + DEBUG ((DEBUG_INFO, "%a, formset: %g is removed because driver
> release 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 already\n", __FUNCTION__, Target->HiiHandle));
> + }
> + } else {
> + //
> + // The HII resource on this HII handle is updated/removed.
> + //
> + FormsetPrivate = GetFormsetPrivateByHiiHandle (Target->HiiHandle,
> FormsetList);
> + if (FormsetPrivate != NULL) {
> + //
> + // HII formset already exist, release it and query again.
> + //
> + DEBUG ((DEBUG_INFO, "%a, formset: %g is updated. Release current
> formset\n", __FUNCTION__, &FormsetPrivate->Guid));
> + RemoveEntryList (&FormsetPrivate->Link);
> + ReleaseFormset (FormsetPrivate);
> + FreePool (FormsetPrivate);
> + }
> +
> + Status = LoadFormsetList (Target->HiiHandle, FormsetList);
> + if (EFI_ERROR (Status)) {
> + DEBUG ((DEBUG_ERROR, "%a, load formset from HII handle: 0x%x
> failed: %r\n", __FUNCTION__, Target->HiiHandle, Status));
> + }
> + }
> +
> + //
> + // Detach it from list first.
> + //
> + RemoveEntryList (&Target->Link);
> + FreePool (Target);
> +
> + PendingListLink = 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 == NULL) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + if (IsListEmpty (&StatementList->StatementList)) {
> + return EFI_SUCCESS;
> + }
> +
> + NextLink = GetFirstNode (&StatementList->StatementList);
> + while (!IsNull (&StatementList->StatementList, NextLink)) {
> + StatementRef =
> REDFISH_PLATFORM_CONFIG_STATEMENT_REF_FROM_LINK (NextLink);
> + NextLink = 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..be2f63df8d 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<BR>
> -
> - SPDX-License-Identifier: BSD-2-Clause-Patent
> -
> -**/
> -
> -#ifndef EDKII_REDFISH_PLATFORM_CONFIG_IMPL_H_
> -#define EDKII_REDFISH_PLATFORM_CONFIG_IMPL_H_
> -
> -#include <Uefi.h>
> -
> -//
> -// Libraries
> -//
> -#include <Library/BaseLib.h>
> -#include <Library/BaseMemoryLib.h>
> -#include <Library/DebugLib.h>
> -#include <Library/DevicePathLib.h>
> -#include <Library/HiiUtilityLib.h>
> -#include <Library/HiiLib.h>
> -#include <Library/MemoryAllocationLib.h>
> -#include <Library/UefiBootServicesTableLib.h>
> -#include <Library/UefiLib.h>
> -
> -#define REDFISH_PLATFORM_CONFIG_DELETE_EXPIRED_FORMSET 0x00
> -#define IS_EMPTY_STRING(a) (a == NULL || a[0] == 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, REDFISH_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 formset data.
> - EFI_GUID Guid; // Formset GUID.
> - EFI_HII_HANDLE HiiHandle; // Hii Handle of this formset.
> - 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 supported 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 token of form title.
> - REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *ParentFormset;
> - HII_FORM *HiiForm; // Pointer to HII form data.
> - LIST_ENTRY StatementList; // Statement list that keep
> statement under this form.
> -} REDFISH_PLATFORM_CONFIG_FORM_PRIVATE;
> -
> -#define REDFISH_PLATFORM_CONFIG_FORM_FROM_LINK(a) BASE_CR (a,
> REDFISH_PLATFORM_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 cache for search
> function.
> -} REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE;
> -
> -#define REDFISH_PLATFORM_CONFIG_STATEMENT_FROM_LINK(a)
> BASE_CR (a, REDFISH_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, REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_REF, Link)
> -
> -//
> -// Definition of REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_LIST
> -//
> -typedef struct {
> - LIST_ENTRY StatementList; // List of
> REDFISH_PLATFORM_CONFIG_STATEMENT_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 recently
> 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
> 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 recently
> 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
> statement 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
> patthern
> - 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
> *RegularExpressionProtocol,
> - 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
> NULL.
> -
> -**/
> -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 responsible
> - 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 string
> 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<BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef EDKII_REDFISH_PLATFORM_CONFIG_IMPL_H_
> +#define EDKII_REDFISH_PLATFORM_CONFIG_IMPL_H_
> +
> +#include <Uefi.h>
> +
> +//
> +// Libraries
> +//
> +#include <Library/BaseLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/DevicePathLib.h>
> +#include <Library/HiiUtilityLib.h>
> +#include <Library/HiiLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/UefiLib.h>
> +
> +#define IS_EMPTY_STRING(a) (a == NULL || a[0] == 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, REDFISH_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 formset data.
> + EFI_GUID Guid; // Formset GUID.
> + EFI_HII_HANDLE HiiHandle; // Hii Handle of this formset.
> + 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 supported 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 token of form title.
> + REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *ParentFormset;
> + HII_FORM *HiiForm; // Pointer to HII form data.
> + LIST_ENTRY StatementList; // Statement list that keep
> statement under this form.
> +} REDFISH_PLATFORM_CONFIG_FORM_PRIVATE;
> +
> +#define REDFISH_PLATFORM_CONFIG_FORM_FROM_LINK(a) BASE_CR (a,
> REDFISH_PLATFORM_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 cache for search
> function.
> +} REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE;
> +
> +#define REDFISH_PLATFORM_CONFIG_STATEMENT_FROM_LINK(a)
> BASE_CR (a, REDFISH_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, REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_REF, Link)
> +
> +//
> +// Definition of REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_LIST
> +//
> +typedef struct {
> + LIST_ENTRY StatementList; // List of
> REDFISH_PLATFORM_CONFIG_STATEMENT_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 recently
> 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
> 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 recently
> 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 statement 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
> patthern
> + 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
> *RegularExpressionProtocol,
> + 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
> NULL.
> +
> +**/
> +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 responsible
> + 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 string
> 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 string from a string package in a English language. The
> + returned string is allocated using AllocatePool(). The caller is responsible
> + 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
The function parameters are not correct.
Thanks
Abner
> + package associated with HiiHandle.
> +
> + @retval NULL The string specified by StringId is not present in the string
> 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
> --
> 2.32.0.windows.2
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [edk2-staging][PATCH v2 1/1] edk2/RedfishPkg: Update Redfish Platform Config Protocol
2022-07-24 13:46 ` Chang, Abner
@ 2022-07-25 3:25 ` Nickle Wang
0 siblings, 0 replies; 3+ messages in thread
From: Nickle Wang @ 2022-07-25 3:25 UTC (permalink / raw)
To: Chang, Abner, devel@edk2.groups.io; +Cc: Yang, Atom, Nick Ramirez
Thanks Abner! Fixed in version 3.
Nickle
-----Original Message-----
From: Chang, Abner <Abner.Chang@amd.com>
Sent: Sunday, July 24, 2022 9:46 PM
To: Wang, Nickle (Server BIOS) <nickle.wang@hpe.com>; devel@edk2.groups.io
Cc: Yang, Atom <Atom.Yang@amd.com>; Nick Ramirez <nramirez@nvidia.com>
Subject: RE: [edk2-staging][PATCH v2 1/1] edk2/RedfishPkg: Update Redfish Platform Config Protocol
[AMD Official Use Only - General]
Thanks Nickle. Two comments in the below.
> -----Original Message-----
> From: Nickle Wang <nickle.wang@hpe.com>
> Sent: Sunday, July 24, 2022 9:20 PM
> To: devel@edk2.groups.io
> Cc: Chang, Abner <Abner.Chang@amd.com>; Yang, Atom
> <Atom.Yang@amd.com>; Nick Ramirez <nramirez@nvidia.com>
> Subject: [edk2-staging][PATCH v2 1/1] edk2/RedfishPkg: Update Redfish
> Platform Config Protocol
>
> [CAUTION: External Email]
>
> 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 <nickle.wang@hpe.com>
> Cc: Abner Chang <abner.chang@amd.com>
> Cc: Yang Atom <Atom.Yang@amd.com>
> Cc: Nick Ramirez <nramirez@nvidia.com>
> ---
> .../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/RedfishPkg/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<BR>
> -
> - 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_PLATFORM_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 = 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_CONFIG_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 configure
> 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_CONFIG_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 configure
> 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 given
> Schema and Pattern.
> -
> - @param[in] This Pointer to
> EDKII_REDFISH_PLATFORM_CONFIG_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
> ConfigureLangList.
> -
> - @retval EFI_SUCCESS ConfigureLangList is returned successfully.
> - @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_CONFIG_PROTOCOL instance.
> - @param[in] HiiHandle The target handle to search. If handle is NULL,
> - this function returns all schema from HII database.
> - @param[out] SupportedSchema The supported schema list which is
> separated 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 using 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, OPTIONAL
> - 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<BR>
> +
> + 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_PLATFORM_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 = 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_CONFIG_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 configure
> 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_CONFIG_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 configure
> 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
> given Schema and RegexPattern.
> +
> + @param[in] This Pointer to
> EDKII_REDFISH_PLATFORM_CONFIG_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
> ConfigureLangList.
> +
> + @retval EFI_SUCCESS ConfigureLangList is returned successfully.
> + @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_CONFIG_PROTOCOL instance.
> + @param[in] HiiHandle The target handle to search. If handle is NULL,
> + this function returns all schema from HII database.
> + @param[out] SupportedSchema The supported schema list which is
> separated 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 using 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, OPTIONAL
> + 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<BR>
> -
> - SPDX-License-Identifier: BSD-2-Clause-Patent
> -
> -**/
> -
> -#include "RedfishPlatformConfigDxe.h"
> -#include "RedfishPlatformConfigImpl.h"
> -
> -REDFISH_PLATFORM_CONFIG_PRIVATE *mRedfishPlatformConfigPrivate =
> 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 second value.
> - -1 is returned when second value is greater than first value.
> -
> -**/
> -UINTN
> -CompareHiiStatementValue (
> - IN HII_STATEMENT_VALUE *Value1,
> - IN HII_STATEMENT_VALUE *Value2
> - )
> -{
> - INTN Result;
> - UINT64 Data1;
> - UINT64 Data2;
> -
> - if (Value1 == NULL || Value2 == NULL) {
> - return 0xFF;
> - }
> -
> - switch (Value1->Type) {
> - case EFI_IFR_TYPE_NUM_SIZE_8:
> - Data1 = Value1->Value.u8;
> - break;
> - case EFI_IFR_TYPE_NUM_SIZE_16:
> - Data1 = Value1->Value.u16;
> - break;
> - case EFI_IFR_TYPE_NUM_SIZE_32:
> - Data1 = Value1->Value.u32;
> - break;
> - case EFI_IFR_TYPE_NUM_SIZE_64:
> - Data1 = Value1->Value.u64;
> - break;
> - case EFI_IFR_TYPE_BOOLEAN:
> - Data1 = (Value1->Value.b ? 1 : 0);
> - break;
> - default:
> - return 0xFF;
> - }
> -
> - switch (Value2->Type) {
> - case EFI_IFR_TYPE_NUM_SIZE_8:
> - Data2 = Value2->Value.u8;
> - break;
> - case EFI_IFR_TYPE_NUM_SIZE_16:
> - Data2 = Value2->Value.u16;
> - break;
> - case EFI_IFR_TYPE_NUM_SIZE_32:
> - Data2 = Value2->Value.u32;
> - break;
> - case EFI_IFR_TYPE_NUM_SIZE_64:
> - Data2 = Value2->Value.u64;
> - break;
> - case EFI_IFR_TYPE_BOOLEAN:
> - Data2 = (Value2->Value.b ? 1 : 0);
> - break;
> - default:
> - return 0xFF;
> - }
> -
> - Result = (Data1 == 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 != EFI_IFR_ONE_OF_OP) {
> - return 0;
> - }
> -
> - if (IsListEmpty (&Statement->HiiStatement->OptionListHead)) {
> - return 0;
> - }
> -
> - Link = GetFirstNode (&Statement->HiiStatement->OptionListHead);
> - while (!IsNull (&Statement->HiiStatement->OptionListHead, Link)) {
> - Option = HII_QUESTION_OPTION_FROM_LINK (Link);
> -
> - if (CompareHiiStatementValue (&Statement->HiiStatement->Value,
> &Option->Value) == 0) {
> - return Option->Text;
> - }
> -
> - Link = 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 == NULL || IS_EMPTY_STRING (HiiString) || Value == NULL) {
> - return EFI_INVALID_PARAMETER;
> - }
> -
> - if (Statement->HiiStatement->Operand != EFI_IFR_ONE_OF_OP) {
> - return EFI_UNSUPPORTED;
> - }
> -
> - if (IsListEmpty (&Statement->HiiStatement->OptionListHead)) {
> - return EFI_NOT_FOUND;
> - }
> -
> - Found = FALSE;
> - Link = GetFirstNode (&Statement->HiiStatement->OptionListHead);
> - while (!IsNull (&Statement->HiiStatement->OptionListHead, Link)) {
> - Option = HII_QUESTION_OPTION_FROM_LINK (Link);
> -
> - TmpString = HiiGetRedfishString (Statement->ParentForm-
> >ParentFormset->HiiHandle, Schema, Option->Text);
> - if (TmpString != NULL) {
> - if (StrCmp (TmpString, HiiString) == 0) {
> - CopyMem (Value, &Option->Value, sizeof (HII_STATEMENT_VALUE));
> - Found = TRUE;
> - }
> - FreePool (TmpString);
> - }
> -
> - if (Found) {
> - return EFI_SUCCESS;
> - }
> -
> - Link = 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 == NULL || RedfishValue == NULL) {
> - return EFI_INVALID_PARAMETER;
> - }
> -
> - switch (Value->Type) {
> - case EFI_IFR_TYPE_NUM_SIZE_8:
> - RedfishValue->Type = REDFISH_VALUE_TYPE_INTEGER;
> - RedfishValue->Value.Integer = (INT64)Value->Value.u8;
> - break;
> - case EFI_IFR_TYPE_NUM_SIZE_16:
> - RedfishValue->Type = REDFISH_VALUE_TYPE_INTEGER;
> - RedfishValue->Value.Integer = (INT64)Value->Value.u16;
> - break;
> - case EFI_IFR_TYPE_NUM_SIZE_32:
> - RedfishValue->Type = REDFISH_VALUE_TYPE_INTEGER;
> - RedfishValue->Value.Integer = (INT64)Value->Value.u32;
> - break;
> - case EFI_IFR_TYPE_NUM_SIZE_64:
> - RedfishValue->Type = REDFISH_VALUE_TYPE_INTEGER;
> - RedfishValue->Value.Integer = (INT64)Value->Value.u64;
> - break;
> - case EFI_IFR_TYPE_BOOLEAN:
> - RedfishValue->Type = REDFISH_VALUE_TYPE_BOOLEAN;
> - RedfishValue->Value.Boolean = Value->Value.b;
> - break;
> - default:
> - RedfishValue->Type = 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 == NULL || RedfishValue == NULL) {
> - return EFI_INVALID_PARAMETER;
> - }
> -
> - switch (RedfishValue->Type) {
> - case REDFISH_VALUE_TYPE_INTEGER:
> - Value->Type = EFI_IFR_TYPE_NUM_SIZE_64;
> - Value->Value.u64 = (UINT64)RedfishValue->Value.Integer;
> - break;
> - case REDFISH_VALUE_TYPE_BOOLEAN:
> - Value->Type = EFI_IFR_TYPE_BOOLEAN;
> - Value->Value.b = RedfishValue->Value.Boolean;
> - break;
> - default:
> - Value->Type = 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 = AsciiStrSize(CONFIGURE_LANGUAGE_PREFIX) + AsciiStrSize (Schema)
> + AsciiStrSize (Version);
> -
> - FullName = AllocatePool (Size);
> - if (FullName == NULL) {
> - DEBUG ((DEBUG_ERROR, "%a, out-of-resource\n", __FUNCTION__));
> - return NULL;
> - }
> -
> - AsciiSPrint (FullName, Size, "%a%a.%a", CONFIGURE_LANGUAGE_PREFIX,
> Schema, 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 refers 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
> *RedfishPlatformConfigPrivate,
> - 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 == NULL || IS_EMPTY_STRING (Schema)
> || IS_EMPTY_STRING (ConfigureLang) || Statement == NULL) {
> - return EFI_INVALID_PARAMETER;
> - }
> -
> - *Statement = NULL;
> -
> - Status = ProcessPendingList (&RedfishPlatformConfigPrivate->FormsetList,
> &RedfishPlatformConfigPrivate->PendingList);
> - if (EFI_ERROR (Status)) {
> - DEBUG ((DEBUG_ERROR, "%a, ProcessPendingList failure: %r\n",
> __FUNCTION__, Status));
> - return Status;
> - }
> -
> - TargetStatement = GetStatementPrivateByConfigureLang
> (&RedfishPlatformConfigPrivate->FormsetList, Schema, ConfigureLang);
> - if (TargetStatement == 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 = 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 ==
> EFI_IFR_TYPE_UNDEFINED) {
> - return EFI_DEVICE_ERROR;
> - }
> -
> - //
> - // Return Value.
> - //
> - *Statement = TargetStatement;
> -
> - return EFI_SUCCESS;
> -}
> -
> -/**
> - Get Redfish value with the given Schema and Configure Language.
> -
> - @param[in] This Pointer to
> EDKII_REDFISH_PLATFORM_CONFIG_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 configure
> 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 == NULL || IS_EMPTY_STRING (Schema) || IS_EMPTY_STRING
> (Version) || IS_EMPTY_STRING (ConfigureLang) || Value == NULL) {
> - return EFI_INVALID_PARAMETER;
> - }
> -
> - RedfishPlatformConfigPrivate =
> REDFISH_PLATFORM_CONFIG_PRIVATE_FROM_THIS (This);
> - Value->Type = REDFISH_VALUE_TYPE_UNKNOWN;
> - FullSchema = NULL;
> - HiiString = NULL;
> -
> - FullSchema = GetFullSchemaString (Schema, Version);
> - if (FullSchema == NULL) {
> - return EFI_OUT_OF_RESOURCES;
> - }
> -
> - Status = RedfishPlatformConfigGetStatementCommon
> (RedfishPlatformConfigPrivate, FullSchema, ConfigureLang,
> &TargetStatement);
> - if (EFI_ERROR (Status)) {
> - goto RELEASE_RESOURCE;
> - }
> -
> - switch (TargetStatement->HiiStatement->Operand) {
> - case EFI_IFR_ONE_OF_OP:
> - StringId = HiiValueToOneOfOptionStringId (TargetStatement);
> - if (StringId == 0) {
> - ASSERT (FALSE);
> - Status = EFI_DEVICE_ERROR;
> - goto RELEASE_RESOURCE;
> - }
> -
> - HiiString = HiiGetRedfishString (TargetStatement->ParentForm-
> >ParentFormset->HiiHandle, FullSchema, StringId);
> - if (HiiString == NULL) {
> - DEBUG ((DEBUG_ERROR, "%a, Can not find string ID: 0x%x with %a\n",
> __FUNCTION__, StringId, FullSchema));
> - Status = EFI_NOT_FOUND;
> - goto RELEASE_RESOURCE;
> - }
> -
> - Size = StrLen (HiiString) + 1;
> - Value->Value.Buffer = AllocatePool (Size);
> - if (Value->Value.Buffer == NULL) {
> - Status = EFI_OUT_OF_RESOURCES;
> - goto RELEASE_RESOURCE;
> - }
> -
> - UnicodeStrToAsciiStrS (HiiString, Value->Value.Buffer, Size);
> - Value->Type = REDFISH_VALUE_TYPE_STRING;
> -
> - break;
> - case EFI_IFR_STRING_OP:
> - if (TargetStatement->HiiStatement->Value.Type !=
> EFI_IFR_TYPE_STRING) {
> - ASSERT (FALSE);
> - Status = EFI_DEVICE_ERROR;
> - goto RELEASE_RESOURCE;
> - }
> -
> - Value->Type = REDFISH_VALUE_TYPE_STRING;
> - Value->Value.Buffer = AllocateCopyPool (StrSize ((CHAR16
> *)TargetStatement->HiiStatement->Value.Buffer), TargetStatement-
> >HiiStatement->Value.Buffer);
> - if (Value->Value.Buffer == NULL) {
> - Status = EFI_OUT_OF_RESOURCES;
> - goto RELEASE_RESOURCE;
> - }
> - break;
> - case EFI_IFR_CHECKBOX_OP:
> - case EFI_IFR_NUMERIC_OP:
> - Status = HiiValueToRedfishNumeric (&TargetStatement->HiiStatement-
> >Value, Value);
> - if (EFI_ERROR (Status)) {
> - DEBUG ((DEBUG_ERROR, "%a, failed to convert HII value to Redfish
> value: %r\n", __FUNCTION__, Status));
> - goto RELEASE_RESOURCE;
> - }
> - break;
> - default:
> - DEBUG ((DEBUG_ERROR, "%a, catch unsupported type: 0x%x! Please
> contact with author if we need to support this type.\n", __FUNCTION__,
> TargetStatement->HiiStatement->Operand));
> - ASSERT (FALSE);
> - Status = EFI_UNSUPPORTED;
> - goto RELEASE_RESOURCE;
> - }
> -
> -RELEASE_RESOURCE:
> -
> - if (FullSchema != NULL) {
> - FreePool (FullSchema);
> - }
> -
> - if (HiiString != 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 == NULL || HiiForm == NULL || HiiStatement == NULL ||
> Value == NULL) {
> - return EFI_INVALID_PARAMETER;
> - }
> -
> - Status = SetQuestionValue (
> - HiiFormset,
> - HiiForm,
> - HiiStatement,
> - Value
> - );
> - if (EFI_ERROR (Status)) {
> - DEBUG ((DEBUG_ERROR, "%a, failed to set question value: %r\n",
> __FUNCTION__, Status));
> - return Status;
> - }
> -
> - Status = 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 refers 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 == NULL || IS_EMPTY_STRING (Schema)
> || IS_EMPTY_STRING (ConfigureLang) || StatementValue == NULL) {
> - return EFI_INVALID_PARAMETER;
> - }
> -
> - TempBuffer = NULL;
> -
> - Status = ProcessPendingList (&RedfishPlatformConfigPrivate->FormsetList,
> &RedfishPlatformConfigPrivate->PendingList);
> - if (EFI_ERROR (Status)) {
> - DEBUG ((DEBUG_ERROR, "%a, ProcessPendingList failure: %r\n",
> __FUNCTION__, Status));
> - return Status;
> - }
> -
> - TargetStatement = GetStatementPrivateByConfigureLang
> (&RedfishPlatformConfigPrivate->FormsetList, Schema, ConfigureLang);
> - if (TargetStatement == 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 != 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 == EFI_IFR_ONE_OF_OP
> && StatementValue->Type == EFI_IFR_TYPE_STRING) {
> - TempBuffer = AllocatePool (StatementValue->BufferLen * sizeof
> (CHAR16));
> - if (TempBuffer == NULL) {
> - return EFI_OUT_OF_RESOURCES;
> - }
> -
> - AsciiStrToUnicodeStrS (StatementValue->Buffer, TempBuffer,
> StatementValue->BufferLen);
> - FreePool (StatementValue->Buffer);
> - StatementValue->Buffer = NULL;
> - StatementValue->BufferLen = 0;
> -
> - Status = HiiStringToOneOfOptionValue (TargetStatement, Schema,
> TempBuffer, 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 ==
> EFI_IFR_NUMERIC_OP && StatementValue->Type ==
> EFI_IFR_TYPE_NUM_SIZE_64) {
> - //
> - // Redfish only has numeric value type and it does not care about the
> value size.
> - // Do a patch here so we have proper value size applied.
> - //
> - StatementValue->Type = 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, TargetStatement->HiiStatement->Value.Type));
> - ASSERT (FALSE);
> - }
> - }
> -
> - Status = 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",
> __FUNCTION__, Status));
> - return Status;
> - }
> -
> - return EFI_SUCCESS;
> -}
> -
> -/**
> - Set Redfish value with the given Schema and Configure Language.
> -
> - @param[in] This Pointer to
> EDKII_REDFISH_PLATFORM_CONFIG_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 configure
> 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 == NULL || IS_EMPTY_STRING (Schema) || IS_EMPTY_STRING
> (Version) || IS_EMPTY_STRING (ConfigureLang)) {
> - return EFI_INVALID_PARAMETER;
> - }
> -
> - if (Value.Type == REDFISH_VALUE_TYPE_UNKNOWN || Value.Type >=
> REDFISH_VALUE_TYPE_MAX) {
> - return EFI_INVALID_PARAMETER;
> - }
> -
> - RedfishPlatformConfigPrivate =
> REDFISH_PLATFORM_CONFIG_PRIVATE_FROM_THIS (This);
> - FullSchema = NULL;
> -
> - FullSchema = GetFullSchemaString (Schema, Version);
> - if (FullSchema == 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 = RedfishNumericToHiiValue (&Value, &NewValue);
> - if (EFI_ERROR (Status)) {
> - DEBUG ((DEBUG_ERROR, "%a, failed to convert Redfish value to Hii
> value: %r\n", __FUNCTION__, Status));
> - goto RELEASE_RESOURCE;
> - }
> - break;
> - case REDFISH_VALUE_TYPE_STRING:
> - NewValue.Type = EFI_IFR_TYPE_STRING;
> - NewValue.BufferLen = (UINT16)AsciiStrSize (Value.Value.Buffer);
> - NewValue.Buffer = AllocateCopyPool (NewValue.BufferLen,
> Value.Value.Buffer);
> - if (NewValue.Buffer == NULL) {
> - Status = EFI_OUT_OF_RESOURCES;
> - goto RELEASE_RESOURCE;
> - }
> - break;
> - default:
> - ASSERT (FALSE);
> - break;
> - }
> -
> - Status = RedfishPlatformConfigSetStatementCommon
> (RedfishPlatformConfigPrivate, FullSchema, ConfigureLang, &NewValue);
> - if (EFI_ERROR (Status)) {
> - DEBUG ((DEBUG_ERROR, "%a, failed to set value to statement: %r\n",
> __FUNCTION__, Status));
> - }
> -
> -RELEASE_RESOURCE:
> -
> - if (FullSchema != NULL) {
> - FreePool (FullSchema);
> - }
> -
> - return Status;
> -}
> -
> -/**
> - Get the list of Configure Language from platform configuration by the given
> Schema and Pattern.
> -
> - @param[in] This Pointer to
> EDKII_REDFISH_PLATFORM_CONFIG_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
> ConfigureLangList.
> -
> - @retval EFI_SUCCESS ConfigureLangList is returned successfully.
> - @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
> *RedfishPlatformConfigPrivate;
> - 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 == NULL || IS_EMPTY_STRING (Schema) || IS_EMPTY_STRING
> (Version) || Count == NULL || ConfigureLangList == NULL ||
> IS_EMPTY_STRING (Pattern)) {
> - return EFI_INVALID_PARAMETER;
> - }
> -
> - *Count = 0;
> - *ConfigureLangList = NULL;
> - FullSchema = NULL;
> - RedfishPlatformConfigPrivate =
> REDFISH_PLATFORM_CONFIG_PRIVATE_FROM_THIS (This);
> -
> - Status = ProcessPendingList (&RedfishPlatformConfigPrivate->FormsetList,
> &RedfishPlatformConfigPrivate->PendingList);
> - if (EFI_ERROR (Status)) {
> - DEBUG ((DEBUG_ERROR, "%a, ProcessPendingList failure: %r\n",
> __FUNCTION__, Status));
> - return Status;
> - }
> -
> - FullSchema = GetFullSchemaString (Schema, Version);
> - if (FullSchema == NULL) {
> - return EFI_OUT_OF_RESOURCES;
> - }
> -
> - Status = GetStatementPrivateByConfigureLangRegex (
> - RedfishPlatformConfigPrivate->RegularExpressionProtocol,
> - &RedfishPlatformConfigPrivate->FormsetList,
> - FullSchema,
> - Pattern,
> - &StatementList
> - );
> - if (EFI_ERROR (Status)) {
> - DEBUG ((DEBUG_ERROR, "%a,
> GetStatementPrivateByConfigureLangRegex failure: %r\n", __FUNCTION__,
> Status));
> - goto RELEASE_RESOURCE;
> - }
> -
> - if (!IsListEmpty (&StatementList.StatementList)) {
> -
> - TmpConfigureLangList = AllocateZeroPool (sizeof (CHAR16 *) *
> StatementList.Count);
> - if (TmpConfigureLangList == NULL) {
> - Status = EFI_OUT_OF_RESOURCES;
> - goto RELEASE_RESOURCE;
> - }
> -
> - Index = 0;
> - NextLink = GetFirstNode (&StatementList.StatementList);
> - while (!IsNull (&StatementList.StatementList, NextLink)) {
> - StatementRef =
> REDFISH_PLATFORM_CONFIG_STATEMENT_REF_FROM_LINK (NextLink);
> - NextLink = GetNextNode (&StatementList.StatementList, NextLink);
> -
> - ASSERT (StatementRef->Statement->Description != 0);
> - if (StatementRef->Statement->Description != 0) {
> - TmpString = HiiGetRedfishString (StatementRef->Statement-
> >ParentForm->ParentFormset->HiiHandle, FullSchema, StatementRef-
> >Statement->Description);
> - ASSERT (TmpString != NULL);
> - if (TmpString != NULL) {
> - TmpConfigureLangList[Index] = AllocateCopyPool (StrSize (TmpString),
> TmpString);
> - ASSERT (TmpConfigureLangList[Index] != NULL);
> - FreePool (TmpString);
> - ++Index;
> - }
> - }
> - }
> - }
> -
> - *Count = StatementList.Count;
> - *ConfigureLangList = TmpConfigureLangList;
> -
> -RELEASE_RESOURCE:
> -
> - if (FullSchema != 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_CONFIG_PROTOCOL instance.
> - @param[in] HiiHandle The target handle to search. If handle is NULL,
> - this function return all schema from HII database.
> - @param[out] SupportedSchema The supported schema list which is
> separated by ';'.
> - The SupportedSchema is allocated by the callee. It's caller's
> - responsibility to free this buffer using 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 == NULL || SupportedSchema == NULL) {
> - return EFI_INVALID_PARAMETER;
> - }
> -
> - *SupportedSchema = NULL;
> -
> - RedfishPlatformConfigPrivate =
> REDFISH_PLATFORM_CONFIG_PRIVATE_FROM_THIS (This);
> -
> - Status = ProcessPendingList (&RedfishPlatformConfigPrivate->FormsetList,
> &RedfishPlatformConfigPrivate->PendingList);
> - if (EFI_ERROR (Status)) {
> - DEBUG ((DEBUG_ERROR, "%a, ProcessPendingList failure: %r\n",
> __FUNCTION__, Status));
> - return Status;
> - }
> -
> - if (IsListEmpty (&RedfishPlatformConfigPrivate->FormsetList)) {
> - return EFI_NOT_FOUND;
> - }
> -
> - //
> - // Calculate for string buffer size.
> - //
> - StringSize = 0;
> - HiiFormsetLink = GetFirstNode (&RedfishPlatformConfigPrivate-
> >FormsetList);
> - while (!IsNull (&RedfishPlatformConfigPrivate->FormsetList,
> HiiFormsetLink)) {
> - HiiFormsetNextLink = GetNextNode (&RedfishPlatformConfigPrivate-
> >FormsetList, HiiFormsetLink);
> - HiiFormsetPrivate =
> REDFISH_PLATFORM_CONFIG_FORMSET_FROM_LINK (HiiFormsetLink);
> -
> - if (HiiHandle != NULL && HiiHandle != HiiFormsetPrivate->HiiHandle) {
> - HiiFormsetLink = HiiFormsetNextLink;
> - continue;
> - }
> -
> - if (HiiFormsetPrivate->SupportedSchema.Count > 0) {
> - for (Index = 0; Index < HiiFormsetPrivate->SupportedSchema.Count;
> Index++) {
> - StringSize += AsciiStrSize (HiiFormsetPrivate-
> >SupportedSchema.SchemaList[Index]);
> - }
> - }
> -
> - HiiFormsetLink = HiiFormsetNextLink;
> - }
> -
> - if (StringSize == 0) {
> - return EFI_NOT_FOUND;
> - }
> -
> - StringBuffer = AllocatePool (StringSize);
> - if (StringBuffer == NULL) {
> - return EFI_OUT_OF_RESOURCES;
> - }
> -
> - StringIndex = 0;
> - HiiFormsetLink = GetFirstNode (&RedfishPlatformConfigPrivate-
> >FormsetList);
> - while (!IsNull (&RedfishPlatformConfigPrivate->FormsetList,
> HiiFormsetLink)) {
> - HiiFormsetNextLink = GetNextNode (&RedfishPlatformConfigPrivate-
> >FormsetList, HiiFormsetLink);
> - HiiFormsetPrivate =
> REDFISH_PLATFORM_CONFIG_FORMSET_FROM_LINK (HiiFormsetLink);
> -
> - if (HiiHandle != NULL && HiiHandle != HiiFormsetPrivate->HiiHandle) {
> - HiiFormsetLink = HiiFormsetNextLink;
> - continue;
> - }
> -
> - if (HiiFormsetPrivate->SupportedSchema.Count > 0) {
> - for (Index = 0; Index < HiiFormsetPrivate->SupportedSchema.Count;
> Index++) {
> - AsciiStrCpyS (&StringBuffer[StringIndex], (StringSize - StringIndex),
> HiiFormsetPrivate->SupportedSchema.SchemaList[Index]);
> - StringIndex += AsciiStrLen (HiiFormsetPrivate-
> >SupportedSchema.SchemaList[Index]);
> - StringBuffer[StringIndex] = ';';
> - ++StringIndex;
> - }
> - }
> -
> - HiiFormsetLink = HiiFormsetNextLink;
> - }
> -
> - StringBuffer[--StringIndex] = '\0';
> -
> - *SupportedSchema = 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 == EFI_HII_DATABASE_NOTIFY_NEW_PACK || NotifyType
> == EFI_HII_DATABASE_NOTIFY_ADD_PACK) {
> - //
> - // HII formset on this handle is updated by driver during run-time. The
> formset needs to be reloaded.
> - //
> - Status = NotifyFormsetUpdate (Handle, &mRedfishPlatformConfigPrivate-
> >PendingList);
> - if (EFI_ERROR (Status)) {
> - DEBUG ((DEBUG_ERROR, "%a, failed to notify updated formset of HII
> handle: 0x%x\n", __FUNCTION__, Handle));
> - return Status;
> - }
> - } else if (NotifyType == EFI_HII_DATABASE_NOTIFY_REMOVE_PACK) {
> - //
> - // HII resource is removed. The formset is no longer exist.
> - //
> - Status = NotifyFormsetDeleted (Handle,
> &mRedfishPlatformConfigPrivate->PendingList);
> - if (EFI_ERROR (Status)) {
> - DEBUG ((DEBUG_ERROR, "%a, failed to notify deleted formset of HII
> handle: 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 = 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 = 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 = 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 = mRedfishPlatformConfigPrivate->HiiDatabase-
> >RegisterPackageNotify (
> - mRedfishPlatformConfigPrivate->HiiDatabase,
> - EFI_HII_PACKAGE_FORMS,
> - NULL,
> - RedfishPlatformConfigFormUpdateNotify,
> - EFI_HII_DATABASE_NOTIFY_NEW_PACK,
> - &mRedfishPlatformConfigPrivate->NotifyHandle
> - );
> - if (EFI_ERROR (Status)) {
> - DEBUG ((DEBUG_ERROR, "%a, RegisterPackageNotify for
> EFI_HII_DATABASE_NOTIFY_NEW_PACK failure: %r\n", __FUNCTION__,
> Status));
> - }
> -
> - //
> - // Register package notification when new form package is updated.
> - //
> - Status = mRedfishPlatformConfigPrivate->HiiDatabase-
> >RegisterPackageNotify (
> - mRedfishPlatformConfigPrivate->HiiDatabase,
> - EFI_HII_PACKAGE_FORMS,
> - NULL,
> - RedfishPlatformConfigFormUpdateNotify,
> - EFI_HII_DATABASE_NOTIFY_ADD_PACK,
> - &mRedfishPlatformConfigPrivate->NotifyHandle
> - );
> - if (EFI_ERROR (Status)) {
> - DEBUG ((DEBUG_ERROR, "%a, RegisterPackageNotify for
> EFI_HII_DATABASE_NOTIFY_NEW_PACK failure: %r\n", __FUNCTION__,
> Status));
> - }
> -
> -#if REDFISH_PLATFORM_CONFIG_DELETE_EXPIRED_FORMSET
> - //
> - // Register package notification when new form package is removed.
> - //
> - Status = mRedfishPlatformConfigPrivate->HiiDatabase-
> >RegisterPackageNotify (
> - mRedfishPlatformConfigPrivate->HiiDatabase,
> - EFI_HII_PACKAGE_FORMS,
> - NULL,
> - RedfishPlatformConfigFormUpdateNotify,
> - EFI_HII_DATABASE_NOTIFY_REMOVE_PACK,
> - &mRedfishPlatformConfigPrivate->NotifyHandle
> - );
> - if (EFI_ERROR (Status)) {
> - DEBUG ((DEBUG_ERROR, "%a, RegisterPackageNotify for
> EFI_HII_DATABASE_NOTIFY_NEW_PACK failure: %r\n", __FUNCTION__,
> Status));
> - }
> -#endif
> -
> - gBS->CloseEvent (Event);
> - mRedfishPlatformConfigPrivate->HiiDbNotify.ProtocolEvent = 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 = gBS->LocateProtocol (
> - &gEfiRegularExpressionProtocolGuid,
> - NULL,
> - (VOID **)&mRedfishPlatformConfigPrivate-
> >RegularExpressionProtocol
> - );
> - if (EFI_ERROR (Status)) {
> - DEBUG ((DEBUG_ERROR, "%a, locate
> EFI_REGULAR_EXPRESSION_PROTOCOL failure: %r\n", __FUNCTION__,
> Status));
> - return;
> - }
> -
> - gBS->CloseEvent (Event);
> - mRedfishPlatformConfigPrivate->RegexNotify.ProtocolEvent = NULL;
> -
> -}
> -
> -/**
> - Unloads an image.
> -
> - @param ImageHandle Handle that identifies the image to be
> unloaded.
> -
> - @retval EFI_SUCCESS The image has been unloaded.
> - @retval EFI_INVALID_PARAMETER ImageHandle is not a valid image handle.
> -
> -**/
> -EFI_STATUS
> -EFIAPI
> -RedfishPlatformConfigDxeUnload (
> - IN EFI_HANDLE ImageHandle
> - )
> -{
> - EFI_STATUS Status;
> -
> - if (mRedfishPlatformConfigPrivate != NULL) {
> - Status = gBS->UninstallProtocolInterface (
> - mRedfishPlatformConfigPrivate->ImageHandle,
> - &gEdkIIRedfishPlatformConfigProtocolGuid,
> - (VOID*)&mRedfishPlatformConfigPrivate->Protocol
> - );
> - if (EFI_ERROR (Status)) {
> - DEBUG ((DEBUG_ERROR, "%a, can not uninstall
> gEdkIIRedfishPlatformConfigProtocolGuid: %r\n", __FUNCTION__, Status));
> - ASSERT (FALSE);
> - }
> -
> - //
> - // Close events
> - //
> - if (mRedfishPlatformConfigPrivate->HiiDbNotify.ProtocolEvent != NULL) {
> - gBS->CloseEvent (mRedfishPlatformConfigPrivate-
> >HiiDbNotify.ProtocolEvent);
> - }
> - if (mRedfishPlatformConfigPrivate->HiiStringNotify.ProtocolEvent != NULL)
> {
> - gBS->CloseEvent (mRedfishPlatformConfigPrivate-
> >HiiStringNotify.ProtocolEvent);
> - }
> - if (mRedfishPlatformConfigPrivate->RegexNotify.ProtocolEvent != NULL) {
> - gBS->CloseEvent (mRedfishPlatformConfigPrivate-
> >RegexNotify.ProtocolEvent);
> - }
> -
> - //
> - // Unregister package notification.
> - //
> - if (mRedfishPlatformConfigPrivate->NotifyHandle != NULL) {
> - mRedfishPlatformConfigPrivate->HiiDatabase->UnregisterPackageNotify
> (
> - mRedfishPlatformConfigPrivate->HiiDatabase,
> - mRedfishPlatformConfigPrivate->NotifyHandle
> - );
> - }
> -
> - ReleaseFormsetList (&mRedfishPlatformConfigPrivate->FormsetList);
> - FreePool (mRedfishPlatformConfigPrivate);
> - mRedfishPlatformConfigPrivate = 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 including
> - 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 = (REDFISH_PLATFORM_CONFIG_PRIVATE
> *)AllocateZeroPool (sizeof (REDFISH_PLATFORM_CONFIG_PRIVATE));
> - if (mRedfishPlatformConfigPrivate == NULL) {
> - DEBUG ((DEBUG_ERROR, "%a, can not allocate pool for
> REDFISH_PLATFORM_CONFIG_PRIVATE\n", __FUNCTION__));
> - ASSERT (FALSE);
> - return EFI_OUT_OF_RESOURCES;
> - }
> -
> - //
> - // Protocol initialization
> - //
> - mRedfishPlatformConfigPrivate->ImageHandle = ImageHandle;
> - mRedfishPlatformConfigPrivate->Protocol.GetValue =
> RedfishPlatformConfigProtocolGetValue;
> - mRedfishPlatformConfigPrivate->Protocol.SetValue =
> RedfishPlatformConfigProtocolSetValue;
> - mRedfishPlatformConfigPrivate->Protocol.GetConfigureLang =
> RedfishPlatformConfigProtocolGetConfigureLang;
> - mRedfishPlatformConfigPrivate->Protocol.GetSupportedSchema =
> RedfishPlatformConfigProtocolGetSupportedSchema;
> -
> - InitializeListHead (&mRedfishPlatformConfigPrivate->FormsetList);
> - InitializeListHead (&mRedfishPlatformConfigPrivate->PendingList);
> -
> - Status = gBS->InstallProtocolInterface (
> - &ImageHandle,
> - &gEdkIIRedfishPlatformConfigProtocolGuid,
> - EFI_NATIVE_INTERFACE,
> - (VOID*)&mRedfishPlatformConfigPrivate->Protocol
> - );
> - if (EFI_ERROR (Status)) {
> - DEBUG ((DEBUG_ERROR, "%a, can not install
> gEdkIIRedfishPlatformConfigProtocolGuid: %r\n", __FUNCTION__, Status));
> - ASSERT (FALSE);
> - }
> -
> - //
> - // Install protocol notification if HII database protocol is installed.
> - //
> - mRedfishPlatformConfigPrivate->HiiDbNotify.ProtocolEvent =
> EfiCreateProtocolNotifyEvent (
> - &gEfiHiiDatabaseProtocolGuid,
> - TPL_CALLBACK,
> - HiiDatabaseProtocolInstalled,
> - NULL,
> - &mRedfishPlatformConfigPrivate-
> >HiiDbNotify.Registration
> - );
> - if (mRedfishPlatformConfigPrivate->HiiDbNotify.ProtocolEvent == NULL) {
> - DEBUG ((DEBUG_ERROR, "%a, failed to create protocol notification for
> gEfiHiiDatabaseProtocolGuid\n", __FUNCTION__));
> - ASSERT (FALSE);
> - }
> -
> - //
> - // Install protocol notification if HII string protocol is installed.
> - //
> - mRedfishPlatformConfigPrivate->HiiStringNotify.ProtocolEvent =
> EfiCreateProtocolNotifyEvent (
> - &gEfiHiiStringProtocolGuid,
> - TPL_CALLBACK,
> - HiiStringProtocolInstalled,
> - NULL,
> - &mRedfishPlatformConfigPrivate-
> >HiiStringNotify.Registration
> - );
> - if (mRedfishPlatformConfigPrivate->HiiStringNotify.ProtocolEvent == NULL)
> {
> - DEBUG ((DEBUG_ERROR, "%a, failed to create protocol notification for
> gEfiHiiStringProtocolGuid\n", __FUNCTION__));
> - ASSERT (FALSE);
> - }
> -
> - //
> - // Install protocol notification if regular expression protocol is installed.
> - //
> - mRedfishPlatformConfigPrivate->RegexNotify.ProtocolEvent =
> EfiCreateProtocolNotifyEvent (
> - &gEfiRegularExpressionProtocolGuid,
> - TPL_CALLBACK,
> - RegexProtocolInstalled,
> - NULL,
> - &mRedfishPlatformConfigPrivate-
> >RegexNotify.Registration
> - );
> - if (mRedfishPlatformConfigPrivate->RegexNotify.ProtocolEvent == NULL) {
> - DEBUG ((DEBUG_ERROR, "%a, failed to create protocol notification for
> gEfiRegularExpressionProtocolGuid\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<BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include "RedfishPlatformConfigDxe.h"
> +#include "RedfishPlatformConfigImpl.h"
> +
> +REDFISH_PLATFORM_CONFIG_PRIVATE *mRedfishPlatformConfigPrivate =
> 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 = 0;
> + switch (Value->Type) {
> + case EFI_IFR_TYPE_NUM_SIZE_8:
> + Temp = Value->Value.u8;
> + break;
> +
> + case EFI_IFR_TYPE_NUM_SIZE_16:
> + Temp = Value->Value.u16;
> + break;
> +
> + case EFI_IFR_TYPE_NUM_SIZE_32:
> + Temp = Value->Value.u32;
> + break;
> +
> + case EFI_IFR_TYPE_BOOLEAN:
> + Temp = 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 buffer.
> +
> + @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 != NULL);
> +
> + switch (Type) {
> + case EFI_IFR_TYPE_NUM_SIZE_8:
> + *(((UINT8 *) Array) + Index) = (UINT8) Value;
> + break;
> +
> + case EFI_IFR_TYPE_NUM_SIZE_16:
> + *(((UINT16 *) Array) + Index) = (UINT16) Value;
> + break;
> +
> + case EFI_IFR_TYPE_NUM_SIZE_32:
> + *(((UINT32 *) Array) + Index) = (UINT32) Value;
> + break;
> +
> + case EFI_IFR_TYPE_NUM_SIZE_64:
> + *(((UINT64 *) Array) + Index) = (UINT64) Value;
> + break;
> +
> + default:
> + break;
> + }
> +}
> +
> +/**
> + Return data element in an Array by its Index in ordered list array buffer.
> +
> + @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 != NULL);
> +
> + Data = 0;
> + switch (Type) {
> + case EFI_IFR_TYPE_NUM_SIZE_8:
> + Data = (UINT64) *(((UINT8 *) Array) + Index);
> + break;
> +
> + case EFI_IFR_TYPE_NUM_SIZE_16:
> + Data = (UINT64) *(((UINT16 *) Array) + Index);
> + break;
> +
> + case EFI_IFR_TYPE_NUM_SIZE_32:
> + Data = (UINT64) *(((UINT32 *) Array) + Index);
> + break;
> +
> + case EFI_IFR_TYPE_NUM_SIZE_64:
> + Data = (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 == NULL) {
> + return 0;
> + }
> +
> + if (HiiStatement->Operand != EFI_IFR_ORDERED_LIST_OP) {
> + return 0;
> + }
> +
> + if (IsListEmpty (&HiiStatement->OptionListHead)) {
> + return 0;
> + }
> +
> + Found = FALSE;
> + Link = GetFirstNode (&HiiStatement->OptionListHead);
> + while (!IsNull (&HiiStatement->OptionListHead, Link)) {
> + Option = HII_QUESTION_OPTION_FROM_LINK (Link);
> +
> + CurrentValue = ExtendHiiValueToU64 (&Option->Value);
> + if (Value == CurrentValue) {
> + return Option->Text;
> + }
> +
> + Link = 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 second value.
> + -1 is returned when second value is greater than first value.
> +
> +**/
> +INTN
> +CompareHiiStatementValue (
> + IN HII_STATEMENT_VALUE *Value1,
> + IN HII_STATEMENT_VALUE *Value2
> + )
> +{
> + INTN Result;
> + UINT64 Data1;
> + UINT64 Data2;
> +
> + if (Value1 == NULL || Value2 == NULL) {
> + return -1;
> + }
> +
> + switch (Value1->Type) {
> + case EFI_IFR_TYPE_NUM_SIZE_8:
> + Data1 = Value1->Value.u8;
> + break;
> + case EFI_IFR_TYPE_NUM_SIZE_16:
> + Data1 = Value1->Value.u16;
> + break;
> + case EFI_IFR_TYPE_NUM_SIZE_32:
> + Data1 = Value1->Value.u32;
> + break;
> + case EFI_IFR_TYPE_NUM_SIZE_64:
> + Data1 = Value1->Value.u64;
> + break;
> + case EFI_IFR_TYPE_BOOLEAN:
> + Data1 = (Value1->Value.b ? 1 : 0);
> + break;
> + default:
> + return -1;
> + }
> +
> + switch (Value2->Type) {
> + case EFI_IFR_TYPE_NUM_SIZE_8:
> + Data2 = Value2->Value.u8;
> + break;
> + case EFI_IFR_TYPE_NUM_SIZE_16:
> + Data2 = Value2->Value.u16;
> + break;
> + case EFI_IFR_TYPE_NUM_SIZE_32:
> + Data2 = Value2->Value.u32;
> + break;
> + case EFI_IFR_TYPE_NUM_SIZE_64:
> + Data2 = Value2->Value.u64;
> + break;
> + case EFI_IFR_TYPE_BOOLEAN:
> + Data2 = (Value2->Value.b ? 1 : 0);
> + break;
> + default:
> + return -1;
> + }
> +
> + Result = (Data1 == 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 != EFI_IFR_ONE_OF_OP) {
> + return 0;
> + }
> +
> + if (IsListEmpty (&Statement->HiiStatement->OptionListHead)) {
> + return 0;
> + }
> +
> + Link = GetFirstNode (&Statement->HiiStatement->OptionListHead);
> + while (!IsNull (&Statement->HiiStatement->OptionListHead, Link)) {
> + Option = HII_QUESTION_OPTION_FROM_LINK (Link);
> +
> + if (CompareHiiStatementValue (&Statement->HiiStatement->Value,
> &Option->Value) == 0) {
> + return Option->Text;
> + }
> +
> + Link = 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 == NULL || IS_EMPTY_STRING (HiiString) || Value == NULL) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + if (Statement->HiiStatement->Operand != EFI_IFR_ONE_OF_OP) {
> + return EFI_UNSUPPORTED;
> + }
> +
> + if (IsListEmpty (&Statement->HiiStatement->OptionListHead)) {
> + return EFI_NOT_FOUND;
> + }
> +
> + Found = FALSE;
> + Link = GetFirstNode (&Statement->HiiStatement->OptionListHead);
> + while (!IsNull (&Statement->HiiStatement->OptionListHead, Link)) {
> + Option = HII_QUESTION_OPTION_FROM_LINK (Link);
> +
> + TmpString = HiiGetRedfishString (Statement->ParentForm-
> >ParentFormset->HiiHandle, Schema, Option->Text);
> + if (TmpString != NULL) {
> + if (StrCmp (TmpString, HiiString) == 0) {
> + CopyMem (Value, &Option->Value, sizeof (HII_STATEMENT_VALUE));
> + Found = TRUE;
> + }
> + FreePool (TmpString);
> + }
> +
> + if (Found) {
> + return EFI_SUCCESS;
> + }
> +
> + Link = 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 == NULL || RedfishValue == NULL) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + switch (Value->Type) {
> + case EFI_IFR_TYPE_NUM_SIZE_8:
> + RedfishValue->Type = REDFISH_VALUE_TYPE_INTEGER;
> + RedfishValue->Value.Integer = (INT64)Value->Value.u8;
> + break;
> + case EFI_IFR_TYPE_NUM_SIZE_16:
> + RedfishValue->Type = REDFISH_VALUE_TYPE_INTEGER;
> + RedfishValue->Value.Integer = (INT64)Value->Value.u16;
> + break;
> + case EFI_IFR_TYPE_NUM_SIZE_32:
> + RedfishValue->Type = REDFISH_VALUE_TYPE_INTEGER;
> + RedfishValue->Value.Integer = (INT64)Value->Value.u32;
> + break;
> + case EFI_IFR_TYPE_NUM_SIZE_64:
> + RedfishValue->Type = REDFISH_VALUE_TYPE_INTEGER;
> + RedfishValue->Value.Integer = (INT64)Value->Value.u64;
> + break;
> + case EFI_IFR_TYPE_BOOLEAN:
> + RedfishValue->Type = REDFISH_VALUE_TYPE_BOOLEAN;
> + RedfishValue->Value.Boolean = Value->Value.b;
> + break;
> + default:
> + RedfishValue->Type = 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 == NULL || RedfishValue == NULL) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + switch (RedfishValue->Type) {
> + case REDFISH_VALUE_TYPE_INTEGER:
> + Value->Type = EFI_IFR_TYPE_NUM_SIZE_64;
> + Value->Value.u64 = (UINT64)RedfishValue->Value.Integer;
> + break;
> + case REDFISH_VALUE_TYPE_BOOLEAN:
> + Value->Type = EFI_IFR_TYPE_BOOLEAN;
> + Value->Value.b = RedfishValue->Value.Boolean;
> + break;
> + default:
> + Value->Type = 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 == NULL || OrderedListStatement->Operand !=
> EFI_IFR_ORDERED_LIST_OP) {
> + return;
> + }
> +
> + DEBUG ((DEBUG_ERROR, "Value.Type= 0x%x\n", OrderedListStatement-
> >Value.Type));
> + DEBUG ((DEBUG_ERROR, "Value.BufferValueType= 0x%x\n",
> OrderedListStatement->Value.BufferValueType));
> + DEBUG ((DEBUG_ERROR, "Value.BufferLen= 0x%x\n",
> OrderedListStatement->Value.BufferLen));
> + DEBUG ((DEBUG_ERROR, "Value.Buffer= 0x%x\n", OrderedListStatement-
> >Value.Buffer));
> + DEBUG ((DEBUG_ERROR, "Value.MaxContainers= 0x%x\n",
> OrderedListStatement->ExtraData.OrderListData.MaxContainers));
> + DEBUG ((DEBUG_ERROR, "StorageWidth= 0x%x\n",
> OrderedListStatement->StorageWidth));
> +
> + if (OrderedListStatement->Value.Buffer == NULL) {
> + return;
> + }
> +
> + Value8 = NULL;
> + Value16 = NULL;
> + Value32 = NULL;
> + Value64 = NULL;
> + Count = 0;
> +
> + switch (OrderedListStatement->Value.BufferValueType) {
> + case EFI_IFR_TYPE_NUM_SIZE_8:
> + Value8 = (UINT8 *)OrderedListStatement->Value.Buffer;
> + Count = OrderedListStatement->StorageWidth / sizeof (UINT8);
> + for (Index = 0; Index < Count; Index++) {
> + DEBUG ((DEBUG_ERROR, "%d ", Value8[Index]));
> + }
> + break;
> + case EFI_IFR_TYPE_NUM_SIZE_16:
> + Value16 = (UINT16 *)OrderedListStatement->Value.Buffer;
> + Count = OrderedListStatement->StorageWidth / sizeof (UINT16);
> + for (Index = 0; Index < Count; Index++) {
> + DEBUG ((DEBUG_ERROR, "%d ", Value16[Index]));
> + }
> + break;
> + case EFI_IFR_TYPE_NUM_SIZE_32:
> + Value32 = (UINT32 *)OrderedListStatement->Value.Buffer;
> + Count = OrderedListStatement->StorageWidth / sizeof (UINT32);
> + for (Index = 0; Index < Count; Index++) {
> + DEBUG ((DEBUG_ERROR, "%d ", Value32[Index]));
> + }
> + break;
> + case EFI_IFR_TYPE_NUM_SIZE_64:
> + Value64 = (UINT64 *)OrderedListStatement->Value.Buffer;
> + Count = OrderedListStatement->StorageWidth / sizeof (UINT64);
> + for (Index = 0; Index < Count; Index++) {
> + DEBUG ((DEBUG_ERROR, "%d ", Value64[Index]));
> + }
> + break;
> + default:
> + Value8 = (UINT8 *)OrderedListStatement->Value.Buffer;
> + Count = OrderedListStatement->StorageWidth / sizeof (UINT8);
> + for (Index = 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 list.
> +
> +**/
> +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 == NULL || ReturnSize == NULL) {
> + return NULL;
> + }
> +
> + *ReturnSize = 0;
> +
> + if (Statement->HiiStatement->Operand != EFI_IFR_ORDERED_LIST_OP) {
> + return NULL;
> + }
> +
> + if (IsListEmpty (&Statement->HiiStatement->OptionListHead)) {
> + return NULL;
> + }
> +
> + DEBUG_CODE (
> + DumpOrderedListValue (Statement->HiiStatement);
> + );
> +
> + OptionCount = 0;
> + Link = GetFirstNode (&Statement->HiiStatement->OptionListHead);
> + while (!IsNull (&Statement->HiiStatement->OptionListHead, Link)) {
> + Option = HII_QUESTION_OPTION_FROM_LINK (Link);
> +
> + ++OptionCount;
> +
> + Link = GetNextNode (&Statement->HiiStatement->OptionListHead, Link);
> + }
> +
> + *ReturnSize = OptionCount;
> + ReturnedArray = AllocatePool (sizeof (EFI_STRING_ID) * OptionCount);
> + if (ReturnedArray == NULL) {
> + DEBUG ((DEBUG_ERROR, "%a, out of resource\n", __FUNCTION__));
> + *ReturnSize = 0;
> + return NULL;
> + }
> +
> + for (Index = 0; Index < OptionCount; Index++) {
> + Value = OrderedListGetArrayData (Statement->HiiStatement-
> >Value.Buffer, Statement->HiiStatement->Value.BufferValueType, Index);
> + ReturnedArray[Index] = 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 == NULL || IS_EMPTY_STRING (HiiString) || Value == NULL) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + *Value = 0;
> +
> + if (Statement->HiiStatement->Operand != EFI_IFR_ORDERED_LIST_OP) {
> + return EFI_UNSUPPORTED;
> + }
> +
> + if (IsListEmpty (&Statement->HiiStatement->OptionListHead)) {
> + return EFI_NOT_FOUND;
> + }
> +
> + Found = FALSE;
> + Link = GetFirstNode (&Statement->HiiStatement->OptionListHead);
> + while (!IsNull (&Statement->HiiStatement->OptionListHead, Link)) {
> + Option = HII_QUESTION_OPTION_FROM_LINK (Link);
> +
> + TmpString = HiiGetRedfishString (Statement->ParentForm-
> >ParentFormset->HiiHandle, Schema, Option->Text);
> + if (TmpString != NULL) {
> + if (StrCmp (TmpString, HiiString) == 0) {
> + *Value = ExtendHiiValueToU64 (&Option->Value);
> + Found = TRUE;
> + }
> + FreePool (TmpString);
> + }
> +
> + if (Found) {
> + return EFI_SUCCESS;
> + }
> +
> + Link = 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 == NULL || AsciiString[0] == '\0') {
> + return NULL;
> + }
> +
> + StringLen = AsciiStrLen (AsciiString) + 1;
> + Buffer = AllocatePool (StringLen * sizeof (CHAR16));
> + if (Buffer == NULL) {
> + return NULL;
> + }
> +
> + Status = 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 = AsciiStrSize(CONFIGURE_LANGUAGE_PREFIX) + AsciiStrSize
> (Schema) + AsciiStrSize (Version);
> +
> + FullName = AllocatePool (Size);
> + if (FullName == NULL) {
> + DEBUG ((DEBUG_ERROR, "%a, out-of-resource\n", __FUNCTION__));
> + return NULL;
> + }
> +
> + AsciiSPrint (FullName, Size, "%a%a.%a", CONFIGURE_LANGUAGE_PREFIX,
> Schema, 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 refers 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
> *RedfishPlatformConfigPrivate,
> + 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 == NULL || IS_EMPTY_STRING (Schema)
> || IS_EMPTY_STRING (ConfigureLang) || Statement == NULL) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + *Statement = NULL;
> +
> + Status = ProcessPendingList (&RedfishPlatformConfigPrivate->FormsetList,
> &RedfishPlatformConfigPrivate->PendingList);
> + if (EFI_ERROR (Status)) {
> + DEBUG ((DEBUG_ERROR, "%a, ProcessPendingList failure: %r\n",
> __FUNCTION__, Status));
> + return Status;
> + }
> +
> + TargetStatement = GetStatementPrivateByConfigureLang
> (&RedfishPlatformConfigPrivate->FormsetList, Schema, ConfigureLang);
> + if (TargetStatement == 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 = 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 ==
> EFI_IFR_TYPE_UNDEFINED) {
> + return EFI_DEVICE_ERROR;
> + }
> +
> + //
> + // Return Value.
> + //
> + *Statement = TargetStatement;
> +
> + return EFI_SUCCESS;
> +}
> +
> +/**
> + Get Redfish value with the given Schema and Configure Language.
> +
> + @param[in] This Pointer to
> EDKII_REDFISH_PLATFORM_CONFIG_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 configure
> 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 == NULL || IS_EMPTY_STRING (Schema) || IS_EMPTY_STRING
> (Version) || IS_EMPTY_STRING (ConfigureLang) || Value == NULL) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + RedfishPlatformConfigPrivate =
> REDFISH_PLATFORM_CONFIG_PRIVATE_FROM_THIS (This);
> + Value->Type = REDFISH_VALUE_TYPE_UNKNOWN;
> + Value->ArrayCount = 0;
> + Count = 0;
> + FullSchema = NULL;
> + HiiString = NULL;
> + StringIdArray = NULL;
> +
> + FullSchema = GetFullSchemaString (Schema, Version);
> + if (FullSchema == NULL) {
> + return EFI_OUT_OF_RESOURCES;
> + }
> +
> + Status = RedfishPlatformConfigGetStatementCommon
> (RedfishPlatformConfigPrivate, FullSchema, ConfigureLang,
> &TargetStatement);
> + if (EFI_ERROR (Status)) {
> + goto RELEASE_RESOURCE;
> + }
> +
> + switch (TargetStatement->HiiStatement->Operand) {
> + case EFI_IFR_ONE_OF_OP:
> + StringId = HiiValueToOneOfOptionStringId (TargetStatement);
> + if (StringId == 0) {
> + ASSERT (FALSE);
> + Status = EFI_DEVICE_ERROR;
> + goto RELEASE_RESOURCE;
> + }
> +
> + Value->Value.Buffer = HiiGetRedfishAsciiString (TargetStatement-
> >ParentForm->ParentFormset->HiiHandle, FullSchema, StringId);
> + if (Value->Value.Buffer == NULL) {
> + Status = EFI_OUT_OF_RESOURCES;
> + goto RELEASE_RESOURCE;
> + }
> +
> + Value->Type = REDFISH_VALUE_TYPE_STRING;
> + break;
> + case EFI_IFR_STRING_OP:
> + if (TargetStatement->HiiStatement->Value.Type !=
> EFI_IFR_TYPE_STRING) {
> + ASSERT (FALSE);
> + Status = EFI_DEVICE_ERROR;
> + goto RELEASE_RESOURCE;
> + }
> +
> + Value->Type = REDFISH_VALUE_TYPE_STRING;
> + Value->Value.Buffer = AllocatePool (StrLen ((CHAR16
> *)TargetStatement->HiiStatement->Value.Buffer) + 1);
> + UnicodeStrToAsciiStrS ((CHAR16 *)TargetStatement->HiiStatement-
> >Value.Buffer, Value->Value.Buffer, StrLen ((CHAR16 *)TargetStatement-
> >HiiStatement->Value.Buffer) + 1);
> + break;
> + case EFI_IFR_CHECKBOX_OP:
> + case EFI_IFR_NUMERIC_OP:
> + Status = HiiValueToRedfishNumeric (&TargetStatement->HiiStatement-
> >Value, Value);
> + if (EFI_ERROR (Status)) {
> + DEBUG ((DEBUG_ERROR, "%a, failed to convert HII value to Redfish
> value: %r\n", __FUNCTION__, Status));
> + goto RELEASE_RESOURCE;
> + }
> + break;
> + case EFI_IFR_ACTION_OP:
> + if (TargetStatement->HiiStatement->Value.Type !=
> EFI_IFR_TYPE_ACTION) {
> + ASSERT (FALSE);
> + Status = EFI_DEVICE_ERROR;
> + goto RELEASE_RESOURCE;
> + }
> +
> + //
> + // Action has no value. Just return unknown type.
> + //
> + Value->Type = REDFISH_VALUE_TYPE_UNKNOWN;
> + break;
> + case EFI_IFR_ORDERED_LIST_OP:
> + StringIdArray = HiiValueToOrderedListOptionStringId (TargetStatement,
> &Count);
> + if (StringIdArray == NULL) {
> + ASSERT (FALSE);
> + Status = EFI_DEVICE_ERROR;
> + goto RELEASE_RESOURCE;
> + }
> +
> + Value->Value.StringArray = AllocatePool (sizeof (CHAR8 *) * Count);
> + if (Value->Value.StringArray == NULL) {
> + ASSERT (FALSE);
> + Status = EFI_OUT_OF_RESOURCES;
> + goto RELEASE_RESOURCE;
> + }
> +
> + for (Index = 0; Index < Count; Index++) {
> + ASSERT (StringIdArray[Index] != 0);
> + Value->Value.StringArray[Index] = HiiGetRedfishAsciiString
> (TargetStatement->ParentForm->ParentFormset->HiiHandle, FullSchema,
> StringIdArray[Index]);
> + }
> +
> + Value->ArrayCount = Count;
> + Value->Type = REDFISH_VALUE_TYPE_STRING_ARRAY;
> + break;
> + default:
> + DEBUG ((DEBUG_ERROR, "%a, catch unsupported type: 0x%x! Please
> contact with author if we need to support this type.\n", __FUNCTION__,
> TargetStatement->HiiStatement->Operand));
> + ASSERT (FALSE);
> + Status = EFI_UNSUPPORTED;
> + goto RELEASE_RESOURCE;
> + }
> +
> +RELEASE_RESOURCE:
> +
> + if (FullSchema != NULL) {
> + FreePool (FullSchema);
> + }
> +
> + if (HiiString != NULL) {
> + FreePool (HiiString);
> + }
> +
> + if (StringIdArray != 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 == NULL || HiiForm == NULL || HiiStatement == NULL ||
> Value == NULL) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + Status = SetQuestionValue (
> + HiiFormset,
> + HiiForm,
> + HiiStatement,
> + Value
> + );
> + if (EFI_ERROR (Status)) {
> + DEBUG ((DEBUG_ERROR, "%a, failed to set question value: %r\n",
> __FUNCTION__, Status));
> + return Status;
> + }
> +
> + Status = 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 refers 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 == NULL || IS_EMPTY_STRING (Schema)
> || IS_EMPTY_STRING (ConfigureLang) || StatementValue == NULL) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + TempBuffer = NULL;
> + StringArray = NULL;
> +
> + Status = ProcessPendingList (&RedfishPlatformConfigPrivate->FormsetList,
> &RedfishPlatformConfigPrivate->PendingList);
> + if (EFI_ERROR (Status)) {
> + DEBUG ((DEBUG_ERROR, "%a, ProcessPendingList failure: %r\n",
> __FUNCTION__, Status));
> + return Status;
> + }
> +
> + TargetStatement = GetStatementPrivateByConfigureLang
> (&RedfishPlatformConfigPrivate->FormsetList, Schema, ConfigureLang);
> + if (TargetStatement == 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 != 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 == EFI_IFR_ONE_OF_OP
> && StatementValue->Type == EFI_IFR_TYPE_STRING) {
> +
> + TempBuffer = StrToUnicodeStr ((CHAR8 *)StatementValue->Buffer);
> + if (TempBuffer == NULL) {
> + return EFI_OUT_OF_RESOURCES;
> + }
> + FreePool (StatementValue->Buffer);
> + StatementValue->Buffer = NULL;
> + StatementValue->BufferLen = 0;
> +
> + Status = HiiStringToOneOfOptionValue (TargetStatement, Schema,
> TempBuffer, 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 ==
> EFI_IFR_ORDERED_LIST_OP && StatementValue->Type ==
> 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 = AllocateZeroPool (TargetStatement->HiiStatement-
> >StorageWidth);
> + if (StringArray == NULL) {
> + return EFI_OUT_OF_RESOURCES;
> + }
> +
> + //
> + // Arrage new option order from input string array
> + //
> + CharArray = (CHAR8 **)StatementValue->Buffer;
> + for (Index = 0; Index < StatementValue->BufferLen; Index++) {
> + TempBuffer = StrToUnicodeStr (CharArray[Index]);
> + if (TempBuffer == NULL) {
> + return EFI_OUT_OF_RESOURCES;
> + }
> +
> + Status = HiiStringToOrderedListOptionValue (TargetStatement, Schema,
> TempBuffer, &Value);
> + if (EFI_ERROR (Status)) {
> + ASSERT (FALSE);
> + continue;
> + }
> + FreePool (TempBuffer);
> + OrderedListSetArrayData (StringArray, TargetStatement->HiiStatement-
> >Value.BufferValueType, Index, Value);
> + }
> +
> + StatementValue->Type = EFI_IFR_TYPE_BUFFER;
> + StatementValue->Buffer = StringArray;
> + StatementValue->BufferLen = TargetStatement->HiiStatement-
> >StorageWidth;
> + StatementValue->BufferValueType = TargetStatement->HiiStatement-
> >Value.BufferValueType;
> + } else if (TargetStatement->HiiStatement->Operand ==
> EFI_IFR_NUMERIC_OP && StatementValue->Type ==
> EFI_IFR_TYPE_NUM_SIZE_64) {
> + //
> + // Redfish only has numeric value type and it does not care about the
> value size.
> + // Do a patch here so we have proper value size applied.
> + //
> + StatementValue->Type = 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, TargetStatement->HiiStatement->Value.Type));
> + ASSERT (FALSE);
> + }
> + }
> +
> + Status = 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",
> __FUNCTION__, Status));
> + return Status;
> + }
> +
> + return EFI_SUCCESS;
> +}
> +
> +/**
> + Set Redfish value with the given Schema and Configure Language.
> +
> + @param[in] This Pointer to
> EDKII_REDFISH_PLATFORM_CONFIG_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 configure
> 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 == NULL || IS_EMPTY_STRING (Schema) || IS_EMPTY_STRING
> (Version) || IS_EMPTY_STRING (ConfigureLang)) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + if (Value.Type == REDFISH_VALUE_TYPE_UNKNOWN || Value.Type >=
> REDFISH_VALUE_TYPE_MAX) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + RedfishPlatformConfigPrivate =
> REDFISH_PLATFORM_CONFIG_PRIVATE_FROM_THIS (This);
> + FullSchema = NULL;
> +
> + FullSchema = GetFullSchemaString (Schema, Version);
> + if (FullSchema == 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 = RedfishNumericToHiiValue (&Value, &NewValue);
> + if (EFI_ERROR (Status)) {
> + DEBUG ((DEBUG_ERROR, "%a, failed to convert Redfish value to Hii
> value: %r\n", __FUNCTION__, Status));
> + goto RELEASE_RESOURCE;
> + }
> + break;
> + case REDFISH_VALUE_TYPE_STRING:
> + NewValue.Type = EFI_IFR_TYPE_STRING;
> + NewValue.BufferLen = (UINT16)AsciiStrSize (Value.Value.Buffer);
> + NewValue.Buffer = AllocateCopyPool (NewValue.BufferLen,
> Value.Value.Buffer);
> + if (NewValue.Buffer == NULL) {
> + Status = EFI_OUT_OF_RESOURCES;
> + goto RELEASE_RESOURCE;
> + }
> + break;
> + case REDFISH_VALUE_TYPE_STRING_ARRAY:
> + NewValue.Type = EFI_IFR_TYPE_STRING;
> + NewValue.BufferLen = (UINT16)Value.ArrayCount;
> + NewValue.Buffer = (UINT8 *)Value.Value.StringArray;
> + break;
> + default:
> + ASSERT (FALSE);
> + break;
> + }
> +
> + Status = RedfishPlatformConfigSetStatementCommon
> (RedfishPlatformConfigPrivate, FullSchema, ConfigureLang, &NewValue);
> + if (EFI_ERROR (Status)) {
> + DEBUG ((DEBUG_ERROR, "%a, failed to set value to statement: %r\n",
> __FUNCTION__, Status));
> + }
> +
> +RELEASE_RESOURCE:
> +
> + if (FullSchema != NULL) {
> + FreePool (FullSchema);
> + }
> +
> + return Status;
> +}
> +
> +/**
> + Get the list of Configure Language from platform configuration by the
> given Schema and RegexPattern.
> +
> + @param[in] This Pointer to
> EDKII_REDFISH_PLATFORM_CONFIG_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
> ConfigureLangList.
> +
> + @retval EFI_SUCCESS ConfigureLangList is returned successfully.
> + @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
> *RedfishPlatformConfigPrivate;
> + 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 == NULL || IS_EMPTY_STRING (Schema) || IS_EMPTY_STRING
> (Version) || Count == NULL || ConfigureLangList == NULL ||
> IS_EMPTY_STRING (RegexPattern)) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + *Count = 0;
> + *ConfigureLangList = NULL;
> + FullSchema = NULL;
> + RedfishPlatformConfigPrivate =
> REDFISH_PLATFORM_CONFIG_PRIVATE_FROM_THIS (This);
> +
> + Status = ProcessPendingList (&RedfishPlatformConfigPrivate->FormsetList,
> &RedfishPlatformConfigPrivate->PendingList);
> + if (EFI_ERROR (Status)) {
> + DEBUG ((DEBUG_ERROR, "%a, ProcessPendingList failure: %r\n",
> __FUNCTION__, Status));
> + return Status;
> + }
> +
> + FullSchema = GetFullSchemaString (Schema, Version);
> + if (FullSchema == NULL) {
> + return EFI_OUT_OF_RESOURCES;
> + }
> +
> + Status = GetStatementPrivateByConfigureLangRegex (
> + RedfishPlatformConfigPrivate->RegularExpressionProtocol,
> + &RedfishPlatformConfigPrivate->FormsetList,
> + FullSchema,
> + RegexPattern,
> + &StatementList
> + );
> + if (EFI_ERROR (Status)) {
> + DEBUG ((DEBUG_ERROR, "%a,
> GetStatementPrivateByConfigureLangRegex failure: %r\n", __FUNCTION__,
> Status));
> + goto RELEASE_RESOURCE;
> + }
> +
> + if (!IsListEmpty (&StatementList.StatementList)) {
> +
> + TmpConfigureLangList = AllocateZeroPool (sizeof (CHAR16 *) *
> StatementList.Count);
> + if (TmpConfigureLangList == NULL) {
> + Status = EFI_OUT_OF_RESOURCES;
> + goto RELEASE_RESOURCE;
> + }
> +
> + Index = 0;
> + NextLink = GetFirstNode (&StatementList.StatementList);
> + while (!IsNull (&StatementList.StatementList, NextLink)) {
> + StatementRef =
> REDFISH_PLATFORM_CONFIG_STATEMENT_REF_FROM_LINK (NextLink);
> + NextLink = GetNextNode (&StatementList.StatementList, NextLink);
> +
> + ASSERT (StatementRef->Statement->Description != 0);
> + if (StatementRef->Statement->Description != 0) {
> + TmpString = HiiGetRedfishString (StatementRef->Statement-
> >ParentForm->ParentFormset->HiiHandle, FullSchema, StatementRef-
> >Statement->Description);
> + ASSERT (TmpString != NULL);
> + if (TmpString != NULL) {
> + TmpConfigureLangList[Index] = AllocateCopyPool (StrSize (TmpString),
> TmpString);
> + ASSERT (TmpConfigureLangList[Index] != NULL);
> + FreePool (TmpString);
> + ++Index;
> + }
> + }
> + }
> + }
> +
> + *Count = StatementList.Count;
> + *ConfigureLangList = TmpConfigureLangList;
> +
> +RELEASE_RESOURCE:
> +
> + if (FullSchema != 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_CONFIG_PROTOCOL instance.
> + @param[in] HiiHandle The target handle to search. If handle is NULL,
> + this function return all schema from HII database.
> + @param[out] SupportedSchema The supported schema list which is
> separated by ';'.
> + The SupportedSchema is allocated by the callee. It's
> caller's
> + responsibility to free this buffer using 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 == NULL || SupportedSchema == NULL) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + *SupportedSchema = NULL;
> +
> + RedfishPlatformConfigPrivate =
> REDFISH_PLATFORM_CONFIG_PRIVATE_FROM_THIS (This);
> +
> + Status = ProcessPendingList (&RedfishPlatformConfigPrivate->FormsetList,
> &RedfishPlatformConfigPrivate->PendingList);
> + if (EFI_ERROR (Status)) {
> + DEBUG ((DEBUG_ERROR, "%a, ProcessPendingList failure: %r\n",
> __FUNCTION__, Status));
> + return Status;
> + }
> +
> + if (IsListEmpty (&RedfishPlatformConfigPrivate->FormsetList)) {
> + return EFI_NOT_FOUND;
> + }
> +
> + //
> + // Calculate for string buffer size.
> + //
> + StringSize = 0;
> + HiiFormsetLink = GetFirstNode (&RedfishPlatformConfigPrivate-
> >FormsetList);
> + while (!IsNull (&RedfishPlatformConfigPrivate->FormsetList,
> HiiFormsetLink)) {
> + HiiFormsetNextLink = GetNextNode (&RedfishPlatformConfigPrivate-
> >FormsetList, HiiFormsetLink);
> + HiiFormsetPrivate =
> REDFISH_PLATFORM_CONFIG_FORMSET_FROM_LINK (HiiFormsetLink);
> +
> + if (HiiHandle != NULL && HiiHandle != HiiFormsetPrivate->HiiHandle) {
> + HiiFormsetLink = HiiFormsetNextLink;
> + continue;
> + }
> +
> + if (HiiFormsetPrivate->SupportedSchema.Count > 0) {
> + for (Index = 0; Index < HiiFormsetPrivate->SupportedSchema.Count;
> Index++) {
> + StringSize += AsciiStrSize (HiiFormsetPrivate-
> >SupportedSchema.SchemaList[Index]);
> + }
> + }
> +
> + HiiFormsetLink = HiiFormsetNextLink;
> + }
> +
> + if (StringSize == 0) {
> + return EFI_NOT_FOUND;
> + }
> +
> + StringBuffer = AllocatePool (StringSize);
> + if (StringBuffer == NULL) {
> + return EFI_OUT_OF_RESOURCES;
> + }
> +
> + StringIndex = 0;
> + HiiFormsetLink = GetFirstNode (&RedfishPlatformConfigPrivate-
> >FormsetList);
> + while (!IsNull (&RedfishPlatformConfigPrivate->FormsetList,
> HiiFormsetLink)) {
> + HiiFormsetNextLink = GetNextNode (&RedfishPlatformConfigPrivate-
> >FormsetList, HiiFormsetLink);
> + HiiFormsetPrivate =
> REDFISH_PLATFORM_CONFIG_FORMSET_FROM_LINK (HiiFormsetLink);
> +
> + if (HiiHandle != NULL && HiiHandle != HiiFormsetPrivate->HiiHandle) {
> + HiiFormsetLink = HiiFormsetNextLink;
> + continue;
> + }
> +
> + if (HiiFormsetPrivate->SupportedSchema.Count > 0) {
> + for (Index = 0; Index < HiiFormsetPrivate->SupportedSchema.Count;
> Index++) {
> + AsciiStrCpyS (&StringBuffer[StringIndex], (StringSize - StringIndex),
> HiiFormsetPrivate->SupportedSchema.SchemaList[Index]);
> + StringIndex += AsciiStrLen (HiiFormsetPrivate-
> >SupportedSchema.SchemaList[Index]);
> + StringBuffer[StringIndex] = ';';
> + ++StringIndex;
> + }
> + }
> +
> + HiiFormsetLink = HiiFormsetNextLink;
> + }
> +
> + StringBuffer[--StringIndex] = '\0';
> +
> + *SupportedSchema = 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 == EFI_HII_DATABASE_NOTIFY_NEW_PACK || NotifyType
> == EFI_HII_DATABASE_NOTIFY_ADD_PACK) {
> + //
> + // HII formset on this handle is updated by driver during run-time. The
> formset needs to be reloaded.
> + //
> + Status = NotifyFormsetUpdate (Handle,
> &mRedfishPlatformConfigPrivate->PendingList);
> + if (EFI_ERROR (Status)) {
> + DEBUG ((DEBUG_ERROR, "%a, failed to notify updated formset of HII
> handle: 0x%x\n", __FUNCTION__, Handle));
> + return Status;
> + }
> + } else if (NotifyType == EFI_HII_DATABASE_NOTIFY_REMOVE_PACK) {
> + //
> + // HII resource is removed. The formset is no longer exist.
> + //
> + Status = NotifyFormsetDeleted (Handle,
> &mRedfishPlatformConfigPrivate->PendingList);
> + if (EFI_ERROR (Status)) {
> + DEBUG ((DEBUG_ERROR, "%a, failed to notify deleted formset of HII
> handle: 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 = 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 = 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 = 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 = mRedfishPlatformConfigPrivate->HiiDatabase-
> >RegisterPackageNotify (
> + mRedfishPlatformConfigPrivate->HiiDatabase,
> + EFI_HII_PACKAGE_FORMS,
> + NULL,
> + RedfishPlatformConfigFormUpdateNotify,
> + EFI_HII_DATABASE_NOTIFY_NEW_PACK,
> + &mRedfishPlatformConfigPrivate->NotifyHandle
> + );
> + if (EFI_ERROR (Status)) {
> + DEBUG ((DEBUG_ERROR, "%a, RegisterPackageNotify for
> EFI_HII_DATABASE_NOTIFY_NEW_PACK failure: %r\n", __FUNCTION__,
> Status));
> + }
> +
> + //
> + // Register package notification when new form package is updated.
> + //
> + Status = mRedfishPlatformConfigPrivate->HiiDatabase-
> >RegisterPackageNotify (
> + mRedfishPlatformConfigPrivate->HiiDatabase,
> + EFI_HII_PACKAGE_FORMS,
> + NULL,
> + RedfishPlatformConfigFormUpdateNotify,
> + EFI_HII_DATABASE_NOTIFY_ADD_PACK,
> + &mRedfishPlatformConfigPrivate->NotifyHandle
> + );
> + if (EFI_ERROR (Status)) {
> + DEBUG ((DEBUG_ERROR, "%a, RegisterPackageNotify for
> EFI_HII_DATABASE_NOTIFY_NEW_PACK failure: %r\n", __FUNCTION__,
> Status));
> + }
> +
> + gBS->CloseEvent (Event);
> + mRedfishPlatformConfigPrivate->HiiDbNotify.ProtocolEvent = 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 = gBS->LocateProtocol (
> + &gEfiRegularExpressionProtocolGuid,
> + NULL,
> + (VOID **)&mRedfishPlatformConfigPrivate-
> >RegularExpressionProtocol
> + );
> + if (EFI_ERROR (Status)) {
> + DEBUG ((DEBUG_ERROR, "%a, locate
> EFI_REGULAR_EXPRESSION_PROTOCOL failure: %r\n", __FUNCTION__,
> Status));
> + return;
> + }
> +
> + gBS->CloseEvent (Event);
> + mRedfishPlatformConfigPrivate->RegexNotify.ProtocolEvent = NULL;
> +
> +}
> +
> +/**
> + Unloads an image.
> +
> + @param ImageHandle Handle that identifies the image to be
> unloaded.
> +
> + @retval EFI_SUCCESS The image has been unloaded.
> + @retval EFI_INVALID_PARAMETER ImageHandle is not a valid image
> handle.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +RedfishPlatformConfigDxeUnload (
> + IN EFI_HANDLE ImageHandle
> + )
> +{
> + EFI_STATUS Status;
> +
> + if (mRedfishPlatformConfigPrivate != NULL) {
> + Status = gBS->UninstallProtocolInterface (
> + mRedfishPlatformConfigPrivate->ImageHandle,
> + &gEdkIIRedfishPlatformConfigProtocolGuid,
> + (VOID*)&mRedfishPlatformConfigPrivate->Protocol
> + );
> + if (EFI_ERROR (Status)) {
> + DEBUG ((DEBUG_ERROR, "%a, can not uninstall
> gEdkIIRedfishPlatformConfigProtocolGuid: %r\n", __FUNCTION__, Status));
> + ASSERT (FALSE);
> + }
> +
> + //
> + // Close events
> + //
> + if (mRedfishPlatformConfigPrivate->HiiDbNotify.ProtocolEvent != NULL) {
> + gBS->CloseEvent (mRedfishPlatformConfigPrivate-
> >HiiDbNotify.ProtocolEvent);
> + }
> + if (mRedfishPlatformConfigPrivate->HiiStringNotify.ProtocolEvent !=
> NULL) {
> + gBS->CloseEvent (mRedfishPlatformConfigPrivate-
> >HiiStringNotify.ProtocolEvent);
> + }
> + if (mRedfishPlatformConfigPrivate->RegexNotify.ProtocolEvent != NULL)
> {
> + gBS->CloseEvent (mRedfishPlatformConfigPrivate-
> >RegexNotify.ProtocolEvent);
> + }
> +
> + //
> + // Unregister package notification.
> + //
> + if (mRedfishPlatformConfigPrivate->NotifyHandle != NULL) {
> + mRedfishPlatformConfigPrivate->HiiDatabase->UnregisterPackageNotify
> (
> + mRedfishPlatformConfigPrivate->HiiDatabase,
> + mRedfishPlatformConfigPrivate->NotifyHandle
> + );
> + }
> +
> + ReleaseFormsetList (&mRedfishPlatformConfigPrivate->FormsetList);
> + FreePool (mRedfishPlatformConfigPrivate);
> + mRedfishPlatformConfigPrivate = 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 including
> + 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 = (REDFISH_PLATFORM_CONFIG_PRIVATE
> *)AllocateZeroPool (sizeof (REDFISH_PLATFORM_CONFIG_PRIVATE));
> + if (mRedfishPlatformConfigPrivate == NULL) {
> + DEBUG ((DEBUG_ERROR, "%a, can not allocate pool for
> REDFISH_PLATFORM_CONFIG_PRIVATE\n", __FUNCTION__));
> + ASSERT (FALSE);
> + return EFI_OUT_OF_RESOURCES;
> + }
> +
> + //
> + // Protocol initialization
> + //
> + mRedfishPlatformConfigPrivate->ImageHandle = ImageHandle;
> + mRedfishPlatformConfigPrivate->Protocol.GetValue =
> RedfishPlatformConfigProtocolGetValue;
> + mRedfishPlatformConfigPrivate->Protocol.SetValue =
> RedfishPlatformConfigProtocolSetValue;
> + mRedfishPlatformConfigPrivate->Protocol.GetConfigureLang =
> RedfishPlatformConfigProtocolGetConfigureLang;
> + mRedfishPlatformConfigPrivate->Protocol.GetSupportedSchema =
> RedfishPlatformConfigProtocolGetSupportedSchema;
> +
> + InitializeListHead (&mRedfishPlatformConfigPrivate->FormsetList);
> + InitializeListHead (&mRedfishPlatformConfigPrivate->PendingList);
> +
> + Status = gBS->InstallProtocolInterface (
> + &ImageHandle,
> + &gEdkIIRedfishPlatformConfigProtocolGuid,
> + EFI_NATIVE_INTERFACE,
> + (VOID*)&mRedfishPlatformConfigPrivate->Protocol
> + );
> + if (EFI_ERROR (Status)) {
> + DEBUG ((DEBUG_ERROR, "%a, can not install
> gEdkIIRedfishPlatformConfigProtocolGuid: %r\n", __FUNCTION__, Status));
> + ASSERT (FALSE);
> + }
> +
> + //
> + // Install protocol notification if HII database protocol is installed.
> + //
> + mRedfishPlatformConfigPrivate->HiiDbNotify.ProtocolEvent =
> EfiCreateProtocolNotifyEvent (
> + &gEfiHiiDatabaseProtocolGuid,
> + TPL_CALLBACK,
> + HiiDatabaseProtocolInstalled,
> + NULL,
> + &mRedfishPlatformConfigPrivate-
> >HiiDbNotify.Registration
> + );
> + if (mRedfishPlatformConfigPrivate->HiiDbNotify.ProtocolEvent == NULL) {
> + DEBUG ((DEBUG_ERROR, "%a, failed to create protocol notification for
> gEfiHiiDatabaseProtocolGuid\n", __FUNCTION__));
> + ASSERT (FALSE);
> + }
> +
> + //
> + // Install protocol notification if HII string protocol is installed.
> + //
> + mRedfishPlatformConfigPrivate->HiiStringNotify.ProtocolEvent =
> EfiCreateProtocolNotifyEvent (
> + &gEfiHiiStringProtocolGuid,
> + TPL_CALLBACK,
> + HiiStringProtocolInstalled,
> + NULL,
> + &mRedfishPlatformConfigPrivate-
> >HiiStringNotify.Registration
> + );
> + if (mRedfishPlatformConfigPrivate->HiiStringNotify.ProtocolEvent == NULL)
> {
> + DEBUG ((DEBUG_ERROR, "%a, failed to create protocol notification for
> gEfiHiiStringProtocolGuid\n", __FUNCTION__));
> + ASSERT (FALSE);
> + }
> +
> + //
> + // Install protocol notification if regular expression protocol is installed.
> + //
> + mRedfishPlatformConfigPrivate->RegexNotify.ProtocolEvent =
> EfiCreateProtocolNotifyEvent (
> + &gEfiRegularExpressionProtocolGuid,
> + TPL_CALLBACK,
> + RegexProtocolInstalled,
> + NULL,
> + &mRedfishPlatformConfigPrivate-
> >RegexNotify.Registration
> + );
> + if (mRedfishPlatformConfigPrivate->RegexNotify.ProtocolEvent == NULL) {
> + DEBUG ((DEBUG_ERROR, "%a, failed to create protocol notification for
> gEfiRegularExpressionProtocolGuid\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<BR>
> -
> - SPDX-License-Identifier: BSD-2-Clause-Patent
> -
> -**/
> -
> -#ifndef EDKII_REDFISH_PLATFORM_CONFIG_DXE_H_
> -#define EDKII_REDFISH_PLATFORM_CONFIG_DXE_H_
> -
> -#include <Uefi.h>
> -
> -//
> -// Libraries
> -//
> -#include <Library/BaseLib.h>
> -#include <Library/BaseMemoryLib.h>
> -#include <Library/DebugLib.h>
> -#include <Library/MemoryAllocationLib.h>
> -#include <Library/PrintLib.h>
> -#include <Library/UefiLib.h>
> -#include <Library/UefiBootServicesTableLib.h>
> -#include <Library/UefiDriverEntryPoint.h>
> -
> -//
> -// Produced Protocols
> -//
> -#include <Protocol/EdkIIRedfishPlatformConfig.h>
> -#include <Protocol/HiiDatabase.h>
> -#include <Protocol/HiiString.h>
> -#include <Protocol/RegularExpressionProtocol.h>
> -
> -//
> -// Definition of EDKII_REDFISH_PLATFORM_CONFIG_NOTIFY.
> -//
> -typedef struct {
> - EFI_EVENT ProtocolEvent; // Protocol notification event.
> - VOID *Registration; // Protocol notification registration.
> -} 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<BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef EDKII_REDFISH_PLATFORM_CONFIG_DXE_H_
> +#define EDKII_REDFISH_PLATFORM_CONFIG_DXE_H_
> +
> +#include <Uefi.h>
> +
> +//
> +// Libraries
> +//
> +#include <Library/BaseLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/PrintLib.h>
> +#include <Library/UefiLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/UefiDriverEntryPoint.h>
> +
> +//
> +// Produced Protocols
> +//
> +#include <Protocol/EdkIIRedfishPlatformConfig.h>
> +#include <Protocol/HiiDatabase.h>
> +#include <Protocol/HiiString.h>
> +#include <Protocol/RegularExpressionProtocol.h>
> +
> +//
> +// Definition of EDKII_REDFISH_PLATFORM_CONFIG_NOTIFY.
> +//
> +typedef struct {
> + EFI_EVENT ProtocolEvent; // Protocol notification event.
> + VOID *Registration; // Protocol notification registration.
> +} 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.inf
> 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<BR>
> -# SPDX-License-Identifier: BSD-2-Clause-Patent
> -#
> -##
> -
> -[Defines]
> - INF_VERSION = 0x00010005
> - BASE_NAME = RedfishPlatformConfigDxe
> - FILE_GUID = BEAEFFE1-0633-41B5-913C-9389339C2927
> - MODULE_TYPE = DXE_DRIVER
> - VERSION_STRING = 1.0
> - ENTRY_POINT = RedfishPlatformConfigDxeEntryPoint
> - UNLOAD_IMAGE = 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<BR>
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> + INF_VERSION = 0x00010005
> + BASE_NAME = RedfishPlatformConfigDxe
> + FILE_GUID = BEAEFFE1-0633-41B5-913C-9389339C2927
> + MODULE_TYPE = DXE_DRIVER
> + VERSION_STRING = 1.0
> + ENTRY_POINT = RedfishPlatformConfigDxeEntryPoint
> + UNLOAD_IMAGE = 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..917f946656 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<BR>
> -
> - 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 == NULL || StringId == 0) {
> - DEBUG ((DEBUG_INFO, "???"));
> - return EFI_INVALID_PARAMETER;
> - }
> -
> - String = HiiGetString (HiiHandle, StringId, NULL);
> - if (String == 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 == NULL) {
> - return EFI_INVALID_PARAMETER;
> - }
> -
> - Index = 0;
> - HiiFormLink = GetFirstNode (&FormsetPrivate->HiiFormList);
> - while (!IsNull (&FormsetPrivate->HiiFormList, HiiFormLink)) {
> - HiiFormPrivate = REDFISH_PLATFORM_CONFIG_FORM_FROM_LINK
> (HiiFormLink);
> - HiiNextFormLink = GetNextNode (&FormsetPrivate->HiiFormList,
> HiiFormLink);
> -
> - DEBUG ((DEBUG_INFO, " [%d] form: %d title: ", ++Index, HiiFormPrivate-
> >Id));
> - DumpHiiString (FormsetPrivate->HiiHandle, HiiFormPrivate->Title);
> - DEBUG ((DEBUG_INFO, "\n"));
> -
> - HiiStatementLink = GetFirstNode (&HiiFormPrivate->StatementList);
> - while (!IsNull (&HiiFormPrivate->StatementList, HiiStatementLink)) {
> - HiiStatementPrivate =
> REDFISH_PLATFORM_CONFIG_STATEMENT_FROM_LINK (HiiStatementLink);
> - HiiNextStatementLink = GetNextNode (&HiiFormPrivate->StatementList,
> HiiStatementLink);
> -
> - DEBUG ((DEBUG_INFO, " QID: 0x%x Prompt: ", HiiStatementPrivate-
> >QuestionId));
> - DumpHiiString (FormsetPrivate->HiiHandle, HiiStatementPrivate-
> >Description);
> - DEBUG ((DEBUG_INFO, "\n"));
> -
> - HiiStatementLink = HiiNextStatementLink;
> - }
> -
> - HiiFormLink = 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 == NULL) {
> - return EFI_INVALID_PARAMETER;
> - }
> -
> - if (IsListEmpty (FormsetList)) {
> - DEBUG ((DEBUG_INFO, "%a, Empty formset list\n", __FUNCTION__));
> - return EFI_SUCCESS;
> - }
> -
> - Index = 0;
> - HiiFormsetLink = GetFirstNode (FormsetList);
> - while (!IsNull (FormsetList, HiiFormsetLink)) {
> - HiiFormsetNextLink = GetNextNode (FormsetList, HiiFormsetLink);
> - HiiFormsetPrivate =
> REDFISH_PLATFORM_CONFIG_FORMSET_FROM_LINK (HiiFormsetLink);
> -
> - DEBUG ((DEBUG_INFO, "[%d] HII Handle: 0x%x formset: %g at %s\n",
> ++Index, HiiFormsetPrivate->HiiHandle, &HiiFormsetPrivate->Guid,
> HiiFormsetPrivate->DevicePathStr));
> - DumpFormset (HiiFormsetPrivate);
> -
> - HiiFormsetLink = 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 responsible
> - 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 string
> 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 == NULL || HiiHandle == NULL
> || StringId == 0 || IS_EMPTY_STRING (Language)) {
> - ASSERT (FALSE);
> - return NULL;
> - }
> -
> - //
> - // Retrieve the size of the string in the string package for the BestLanguage
> - //
> - StringSize = 0;
> - Status = 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
> GetString()
> - // returns an error other than EFI_BUFFER_TOO_SMALL, then HiiHandle is
> not present
> - // in the HII Database
> - //
> - if (Status != EFI_BUFFER_TOO_SMALL) {
> - return NULL;
> - }
> -
> - //
> - // Allocate a buffer for the return string
> - //
> - String = AllocateZeroPool (StringSize);
> - if (String == NULL) {
> - return NULL;
> - }
> -
> - //
> - // Retrieve the string from the string package
> - //
> - Status = 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 = 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 string
> 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
> otherwise.
> -
> -**/
> -BOOLEAN
> -CheckSupportedSchema (
> - IN REDFISH_PLATFORM_CONFIG_SCHEMA *SupportedSchema,
> - IN CHAR8 *Schema
> - )
> -{
> - UINTN Index;
> -
> - if (SupportedSchema == NULL || IS_EMPTY_STRING (Schema)) {
> - return FALSE;
> - }
> -
> - if (SupportedSchema->Count == 0) {
> - return FALSE;
> - }
> -
> - for (Index = 0; Index < SupportedSchema->Count; Index++) {
> - if (AsciiStrCmp (SupportedSchema->SchemaList[Index], Schema) == 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 NULL.
> - @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 == NULL || SupportedSchema == NULL) {
> - return EFI_INVALID_PARAMETER;
> - }
> -
> - SupportedSchema->Count = 0;
> -
> - SupportedLanguages = HiiGetSupportedLanguages (HiiHandle);
> - if (SupportedLanguages == NULL) {
> - return EFI_NOT_FOUND;
> - }
> -
> - Index = 0;
> - LangIndex = 0;
> - Count = 0;
> - while (TRUE) {
> - if (SupportedLanguages[Index] == ';' || SupportedLanguages[Index] ==
> '\0') {
> - if (AsciiStrnCmp (&SupportedLanguages[LangIndex],
> X_UEFI_SCHEMA_PREFIX, AsciiStrLen (X_UEFI_SCHEMA_PREFIX)) == 0) {
> - ++Count;
> - }
> - LangIndex = Index + 1;
> - }
> -
> - if (SupportedLanguages[Index] == '\0') {
> - break;
> - }
> -
> - ++Index;
> - }
> -
> - if (Count == 0) {
> - return EFI_NOT_FOUND;
> - }
> -
> - SupportedSchema->Count = Count;
> - SupportedSchema->SchemaList = AllocatePool (sizeof (CHAR8 *) * Count);
> - if (SupportedSchema->SchemaList == NULL) {
> - return EFI_OUT_OF_RESOURCES;
> - }
> -
> - Index = 0;
> - LangIndex = 0;
> - ListIndex = 0;
> - while (TRUE) {
> -
> - if (SupportedLanguages[Index] == ';' || SupportedLanguages[Index] ==
> '\0') {
> - if (AsciiStrnCmp (&SupportedLanguages[LangIndex],
> X_UEFI_SCHEMA_PREFIX, AsciiStrLen (X_UEFI_SCHEMA_PREFIX)) == 0) {
> - StrSize = Index - LangIndex;
> - SupportedSchema->SchemaList[ListIndex] = AllocateCopyPool ((StrSize
> + 1), &SupportedLanguages[LangIndex]);
> - SupportedSchema->SchemaList[ListIndex][StrSize] = '\0';
> - ++ListIndex;
> - }
> -
> - LangIndex = Index + 1;
> - }
> -
> - if (SupportedLanguages[Index] == '\0') {
> - break;
> - }
> -
> - ++Index;
> - }
> -
> - return EFI_SUCCESS;
> -}
> -
> -/**
> - Search and find statement private instance by given regular expression
> patthern
> - 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
> *RegularExpressionProtocol,
> - 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 == NULL || IS_EMPTY_STRING (Schema) ||
> IS_EMPTY_STRING (Pattern) || StatementList == NULL) {
> - return EFI_INVALID_PARAMETER;
> - }
> -
> - if (RegularExpressionProtocol == NULL) {
> - return EFI_NOT_READY;
> - }
> -
> - StatementList->Count = 0;
> - InitializeListHead (&StatementList->StatementList);
> -
> - if (IsListEmpty (FormsetList)) {
> - return EFI_NOT_FOUND;
> - }
> -
> - HiiFormsetLink = GetFirstNode (FormsetList);
> - while (!IsNull (FormsetList, HiiFormsetLink)) {
> - HiiFormsetNextLink = GetNextNode (FormsetList, HiiFormsetLink);
> - HiiFormsetPrivate =
> REDFISH_PLATFORM_CONFIG_FORMSET_FROM_LINK (HiiFormsetLink);
> -
> - //
> - // Performance check.
> - // If there is no desired Redfish schema found, skip this formset.
> - //
> - if (!CheckSupportedSchema (&HiiFormsetPrivate->SupportedSchema,
> Schema)) {
> - HiiFormsetLink = HiiFormsetNextLink;
> - continue;
> - }
> -
> - HiiFormLink = GetFirstNode (&HiiFormsetPrivate->HiiFormList);
> - while (!IsNull (&HiiFormsetPrivate->HiiFormList, HiiFormLink)) {
> - HiiNextFormLink = GetNextNode (&HiiFormsetPrivate->HiiFormList,
> HiiFormLink);
> - HiiFormPrivate = REDFISH_PLATFORM_CONFIG_FORM_FROM_LINK
> (HiiFormLink);
> -
> - HiiStatementLink =GetFirstNode (&HiiFormPrivate->StatementList);
> - while (!IsNull (&HiiFormPrivate->StatementList, HiiStatementLink)) {
> - HiiNextStatementLink = GetNextNode (&HiiFormPrivate->StatementList,
> HiiStatementLink);
> - HiiStatementPrivate =
> REDFISH_PLATFORM_CONFIG_STATEMENT_FROM_LINK (HiiStatementLink);
> -
> - if (HiiStatementPrivate->Description != 0) {
> - TmpString = HiiGetRedfishString (HiiFormsetPrivate->HiiHandle,
> Schema, HiiStatementPrivate->Description);
> - if (TmpString != NULL) {
> - Status = RegularExpressionProtocol->MatchString (
> - RegularExpressionProtocol,
> - TmpString,
> - Pattern,
> - &gEfiRegexSyntaxTypePerlGuid,
> - &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 = AllocateZeroPool (sizeof
> (REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_REF));
> - if (StatementRef == NULL) {
> - return EFI_OUT_OF_RESOURCES;
> - }
> -
> - StatementRef->Statement = HiiStatementPrivate;
> - InsertTailList (&StatementList->StatementList, &StatementRef->Link);
> - ++StatementList->Count;
> - }
> -
> - FreePool (TmpString);
> - }
> - }
> -
> - HiiStatementLink = HiiNextStatementLink;
> - }
> -
> - HiiFormLink = HiiNextFormLink;
> - }
> -
> - HiiFormsetLink = 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
> statement 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 == NULL || IS_EMPTY_STRING (Schema) ||
> IS_EMPTY_STRING (ConfigureLang)) {
> - return NULL;
> - }
> -
> - if (IsListEmpty (FormsetList)) {
> - return NULL;
> - }
> -
> - HiiFormsetLink = GetFirstNode (FormsetList);
> - while (!IsNull (FormsetList, HiiFormsetLink)) {
> - HiiFormsetNextLink = GetNextNode (FormsetList, HiiFormsetLink);
> - HiiFormsetPrivate =
> REDFISH_PLATFORM_CONFIG_FORMSET_FROM_LINK (HiiFormsetLink);
> -
> - //
> - // Performance check.
> - // If there is no desired Redfish schema found, skip this formset.
> - //
> - if (!CheckSupportedSchema (&HiiFormsetPrivate->SupportedSchema,
> Schema)) {
> - HiiFormsetLink = HiiFormsetNextLink;
> - continue;
> - }
> -
> - HiiFormLink = GetFirstNode (&HiiFormsetPrivate->HiiFormList);
> - while (!IsNull (&HiiFormsetPrivate->HiiFormList, HiiFormLink)) {
> - HiiNextFormLink = GetNextNode (&HiiFormsetPrivate->HiiFormList,
> HiiFormLink);
> - HiiFormPrivate = REDFISH_PLATFORM_CONFIG_FORM_FROM_LINK
> (HiiFormLink);
> -
> - HiiStatementLink =GetFirstNode (&HiiFormPrivate->StatementList);
> - while (!IsNull (&HiiFormPrivate->StatementList, HiiStatementLink)) {
> - HiiNextStatementLink = GetNextNode (&HiiFormPrivate->StatementList,
> HiiStatementLink);
> - HiiStatementPrivate =
> REDFISH_PLATFORM_CONFIG_STATEMENT_FROM_LINK (HiiStatementLink);
> -
> - DEBUG_CODE (
> - STATIC UINTN Index = 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 != 0) {
> - TmpString = HiiGetRedfishString (HiiFormsetPrivate->HiiHandle,
> Schema, HiiStatementPrivate->Description);
> - if (TmpString != NULL) {
> - if (StrCmp (TmpString, ConfigureLang) == 0) {
> - FreePool (TmpString);
> - return HiiStatementPrivate;
> - }
> -
> - FreePool (TmpString);
> - }
> - }
> -
> - HiiStatementLink = HiiNextStatementLink;
> - }
> -
> - HiiFormLink = HiiNextFormLink;
> - }
> -
> - HiiFormsetLink = 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 == NULL || FormsetList == NULL) {
> - return NULL;
> - }
> -
> - if (IsListEmpty (FormsetList)) {
> - return NULL;
> - }
> -
> - HiiFormsetLink = GetFirstNode (FormsetList);
> - while (!IsNull (FormsetList, HiiFormsetLink)) {
> - HiiFormsetNextLink = GetNextNode (FormsetList, HiiFormsetLink);
> - HiiFormsetPrivate =
> REDFISH_PLATFORM_CONFIG_FORMSET_FROM_LINK (HiiFormsetLink);
> -
> - if (HiiFormsetPrivate->HiiHandle == HiiHandle) {
> - return HiiFormsetPrivate;
> - }
> -
> - HiiFormsetLink = HiiFormsetNextLink;
> - }
> -
> - return NULL;
> -}
> -
> -/**
> - Release formset and all the forms and statements that belong to this
> formset.
> -
> - @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 == NULL) {
> - return EFI_INVALID_PARAMETER;
> - }
> -
> - HiiFormLink = GetFirstNode (&FormsetPrivate->HiiFormList);
> - while (!IsNull (&FormsetPrivate->HiiFormList, HiiFormLink)) {
> - HiiFormPrivate = REDFISH_PLATFORM_CONFIG_FORM_FROM_LINK
> (HiiFormLink);
> - HiiNextFormLink = GetNextNode (&FormsetPrivate->HiiFormList,
> HiiFormLink);
> -
> - HiiStatementLink = GetFirstNode (&HiiFormPrivate->StatementList);
> - while (!IsNull (&HiiFormPrivate->StatementList, HiiStatementLink)) {
> - HiiStatementPrivate =
> REDFISH_PLATFORM_CONFIG_STATEMENT_FROM_LINK (HiiStatementLink);
> - HiiNextStatementLink = GetNextNode (&HiiFormPrivate->StatementList,
> HiiStatementLink);
> -
> - //
> - // HiiStatementPrivate->HiiStatement will be released in
> DestroyFormSet().
> - //
> -
> - if (HiiStatementPrivate->DesStringCache != NULL) {
> - FreePool (HiiStatementPrivate->DesStringCache);
> - HiiStatementPrivate->DesStringCache = NULL;
> - }
> -
> - RemoveEntryList (&HiiStatementPrivate->Link);
> - FreePool (HiiStatementPrivate);
> - HiiStatementLink = HiiNextStatementLink;
> - }
> -
> - //
> - // HiiStatementPrivate->HiiForm will be released in DestroyFormSet().
> - //
> -
> - RemoveEntryList (&HiiFormPrivate->Link);
> - FreePool (HiiFormPrivate);
> - HiiFormLink = HiiNextFormLink;
> - }
> -
> - if (FormsetPrivate->HiiFormSet != NULL) {
> - DestroyFormSet (FormsetPrivate->HiiFormSet);
> - FormsetPrivate->HiiFormSet = NULL;
> - }
> -
> - FreePool (FormsetPrivate->DevicePathStr);
> -
> - //
> - // Release schema list
> - //
> - if (FormsetPrivate->SupportedSchema.SchemaList != NULL) {
> - for (Index = 0; Index < FormsetPrivate->SupportedSchema.Count;
> Index++) {
> - FreePool (FormsetPrivate->SupportedSchema.SchemaList[Index]);
> - }
> -
> - FreePool (FormsetPrivate->SupportedSchema.SchemaList);
> - FormsetPrivate->SupportedSchema.SchemaList = NULL;
> - FormsetPrivate->SupportedSchema.Count = 0;
> - }
> -
> - return EFI_SUCCESS;
> -}
> -
> -/**
> - Create new form-set instance.
> -
> - @retval REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE * Pointer to
> newly created form-set private instance.
> -
> -**/
> -REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *
> -NewFormsetPrivate (
> - VOID
> - )
> -{
> - REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *NewFormsetPrivate;
> -
> - NewFormsetPrivate = AllocateZeroPool (sizeof
> (REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE));
> - if (NewFormsetPrivate == 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 == NULL || FormsetPrivate == NULL) {
> - return EFI_INVALID_PARAMETER;
> - }
> -
> -
> - HiiFormSet = AllocateZeroPool (sizeof (HII_FORMSET));
> - if (HiiFormSet == NULL) {
> - return EFI_OUT_OF_RESOURCES;
> - }
> -
> - //
> - // Find HII formset by the given HII handle.
> - //
> - ZeroMem (&ZeroGuid, sizeof (ZeroGuid));
> - Status = CreateFormSetFromHiiHandle (HiiHandle, &ZeroGuid, HiiFormSet);
> - if (EFI_ERROR (Status) || IsListEmpty (&HiiFormSet->FormListHead)) {
> - Status = EFI_NOT_FOUND;
> - goto ErrorExit;
> - }
> -
> - //
> - // Initialize formset
> - //
> - InitializeFormSet (HiiFormSet);
> -
> - //
> - // Initialize formset private data.
> - //
> - FormsetPrivate->HiiFormSet = HiiFormSet;
> - FormsetPrivate->HiiHandle = HiiHandle;
> - CopyGuid (&FormsetPrivate->Guid, &HiiFormSet->Guid);
> - FormsetPrivate->DevicePathStr = ConvertDevicePathToText (HiiFormSet-
> >DevicePath, FALSE, FALSE);
> - Status = GetSupportedSchema (FormsetPrivate->HiiHandle,
> &FormsetPrivate->SupportedSchema);
> - if (EFI_ERROR (Status)) {
> - DEBUG ((DEBUG_WARN, "%a, No schema from HII handle: 0x%x found:
> %r\n", __FUNCTION__, FormsetPrivate->HiiHandle, Status));
> - }
> -
> - HiiFormLink = GetFirstNode (&HiiFormSet->FormListHead);
> - while (!IsNull (&HiiFormSet->FormListHead, HiiFormLink)) {
> - HiiForm = HII_FORM_FROM_LINK (HiiFormLink);
> -
> - HiiFormPrivate = AllocateZeroPool (sizeof
> (REDFISH_PLATFORM_CONFIG_FORM_PRIVATE));
> - if (HiiFormPrivate == NULL) {
> - Status = EFI_OUT_OF_RESOURCES;
> - goto ErrorExit;
> - }
> -
> - //
> - // Initialize form private data.
> - //
> - HiiFormPrivate->HiiForm = HiiForm;
> - HiiFormPrivate->Id = HiiForm->FormId;
> - HiiFormPrivate->Title = HiiForm->FormTitle;
> - HiiFormPrivate->ParentFormset = FormsetPrivate;
> - InitializeListHead (&HiiFormPrivate->StatementList);
> -
> - HiiStatementLink = GetFirstNode (&HiiForm->StatementListHead);
> - while (!IsNull (&HiiForm->StatementListHead, HiiStatementLink)) {
> - HiiStatement = HII_STATEMENT_FROM_LINK (HiiStatementLink);
> -
> - HiiStatementPrivate = AllocateZeroPool (sizeof
> (REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE));
> - if (HiiStatementPrivate == NULL) {
> - Status = EFI_OUT_OF_RESOURCES;
> - goto ErrorExit;
> - }
> - //
> - // Initialize statement private data.
> - //
> - HiiStatementPrivate->HiiStatement = HiiStatement;
> - HiiStatementPrivate->QuestionId = HiiStatement->QuestionId;
> - HiiStatementPrivate->Description = HiiStatement->Prompt;
> - HiiStatementPrivate->ParentForm = HiiFormPrivate;
> -
> - //
> - // Attach to statement list.
> - //
> - InsertTailList (&HiiFormPrivate->StatementList, &HiiStatementPrivate-
> >Link);
> - HiiStatementLink = GetNextNode (&HiiForm->StatementListHead,
> HiiStatementLink);
> - }
> - //
> - // Attach to form list.
> - //
> - InsertTailList (&FormsetPrivate->HiiFormList, &HiiFormPrivate->Link);
> - HiiFormLink = GetNextNode (&HiiFormSet->FormListHead, HiiFormLink);
> - }
> -
> - return EFI_SUCCESS;
> -
> -ErrorExit:
> -
> - //
> - // Release HiiFormSet if HiiFormSet is not linked to FormsetPrivate yet.
> - //
> - if (HiiFormSet != NULL && FormsetPrivate->HiiFormSet != 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 == NULL || FormsetList == NULL) {
> - return EFI_INVALID_PARAMETER;
> - }
> -
> - FormsetPrivate = GetFormsetPrivateByHiiHandle (HiiHandle, FormsetList);
> - if (FormsetPrivate != NULL) {
> - return EFI_ALREADY_STARTED;
> - }
> -
> - FormsetPrivate = NewFormsetPrivate ();
> - if (FormsetPrivate == NULL) {
> - DEBUG ((DEBUG_ERROR, "%a, out of resource\n", __FUNCTION__));
> - return EFI_OUT_OF_RESOURCES;
> - }
> -
> - //
> - // Load formset on the given HII handle.
> - //
> - Status = 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 == NULL) {
> - return EFI_INVALID_PARAMETER;
> - }
> -
> - if (IsListEmpty (FormsetList)) {
> - return EFI_SUCCESS;
> - }
> -
> - HiiFormsetLink = GetFirstNode (FormsetList);
> - while (!IsNull (FormsetList, HiiFormsetLink)) {
> - HiiFormsetNextLink = GetNextNode (FormsetList, HiiFormsetLink);
> - HiiFormsetPrivate =
> REDFISH_PLATFORM_CONFIG_FORMSET_FROM_LINK (HiiFormsetLink);
> -
> - //
> - // Detach from list.
> - //
> - RemoveEntryList (&HiiFormsetPrivate->Link);
> - ReleaseFormset (HiiFormsetPrivate);
> - FreePool (HiiFormsetPrivate);
> - HiiFormsetLink = 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 == NULL || PendingList == NULL) {
> - return NULL;
> - }
> -
> - if (IsListEmpty (PendingList)) {
> - return NULL;
> - }
> -
> - PendingListLink = GetFirstNode (PendingList);
> - while (!IsNull (PendingList, PendingListLink)) {
> - Target = REDFISH_PLATFORM_CONFIG_PENDING_LIST_FROM_LINK
> (PendingListLink);
> -
> - if (Target->HiiHandle == HiiHandle) {
> - return Target;
> - }
> -
> - PendingListLink = 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 recently
> 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 == NULL || PendingList == NULL) {
> - return EFI_INVALID_PARAMETER;
> - }
> -
> - //
> - // Check and see if this HII handle is processed already.
> - //
> - TargetPendingList = GetPendingList (HiiHandle, PendingList);
> - if (TargetPendingList != NULL) {
> - TargetPendingList->IsDeleted = FALSE;
> - DEBUG_CODE (
> - DEBUG ((DEBUG_INFO, "%a, HII handle: 0x%x is updated\n",
> __FUNCTION__, HiiHandle));
> - );
> - return EFI_SUCCESS;
> - }
> -
> - TargetPendingList= AllocateZeroPool (sizeof
> (REDFISH_PLATFORM_CONFIG_PENDING_LIST));
> - if (TargetPendingList == NULL) {
> - return EFI_OUT_OF_RESOURCES;
> - }
> -
> - TargetPendingList->HiiHandle = HiiHandle;
> - TargetPendingList->IsDeleted = 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
> 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 recently
> 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 == NULL || PendingList == NULL) {
> - return EFI_INVALID_PARAMETER;
> - }
> -
> - //
> - // Check and see if this HII handle is processed already.
> - //
> - TargetPendingList = GetPendingList (HiiHandle, PendingList);
> - if (TargetPendingList != NULL) {
> - TargetPendingList->IsDeleted = TRUE;
> - DEBUG_CODE (
> - DEBUG ((DEBUG_INFO, "%a, HII handle: 0x%x is updated and deleted\n",
> __FUNCTION__, HiiHandle));
> - );
> - return EFI_SUCCESS;
> - }
> -
> - TargetPendingList= AllocateZeroPool (sizeof
> (REDFISH_PLATFORM_CONFIG_PENDING_LIST));
> - if (TargetPendingList == NULL) {
> - return EFI_OUT_OF_RESOURCES;
> - }
> -
> - TargetPendingList->HiiHandle = HiiHandle;
> - TargetPendingList->IsDeleted = 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
> NULL.
> -
> -**/
> -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 == NULL || PendingList == NULL) {
> - return EFI_INVALID_PARAMETER;
> - }
> -
> - if (IsListEmpty (PendingList)) {
> - return EFI_SUCCESS;
> - }
> -
> - PendingListLink = GetFirstNode (PendingList);
> - while (!IsNull (PendingList, PendingListLink)) {
> - PendingListNextLink = GetNextNode (PendingList, PendingListLink);
> - Target = REDFISH_PLATFORM_CONFIG_PENDING_LIST_FROM_LINK
> (PendingListLink);
> -
> - if (Target->IsDeleted) {
> - //
> - // The HII resource on this HII handle is removed. Release the formset.
> - //
> - FormsetPrivate = GetFormsetPrivateByHiiHandle (Target->HiiHandle,
> FormsetList);
> - if (FormsetPrivate != NULL) {
> - DEBUG ((DEBUG_INFO, "%a, formset: %g is removed because driver
> release 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
> already\n", __FUNCTION__, Target->HiiHandle));
> - }
> - } else {
> - //
> - // The HII resource on this HII handle is updated/removed.
> - //
> - FormsetPrivate = GetFormsetPrivateByHiiHandle (Target->HiiHandle,
> FormsetList);
> - if (FormsetPrivate != NULL) {
> - //
> - // HII formset already exist, release it and query again.
> - //
> - DEBUG ((DEBUG_INFO, "%a, formset: %g is updated. Release current
> formset\n", __FUNCTION__, &FormsetPrivate->Guid));
> - RemoveEntryList (&FormsetPrivate->Link);
> - ReleaseFormset (FormsetPrivate);
> - FreePool (FormsetPrivate);
> - }
> -
> - Status = LoadFormsetList (Target->HiiHandle, FormsetList);
> - if (EFI_ERROR (Status)) {
> - DEBUG ((DEBUG_ERROR, "%a, load formset from HII handle: 0x%x failed:
> %r\n", __FUNCTION__, Target->HiiHandle, Status));
> - }
> - }
> -
> - //
> - // Detach it from list first.
> - //
> - RemoveEntryList (&Target->Link);
> - FreePool (Target);
> -
> - PendingListLink = 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 == NULL) {
> - return EFI_INVALID_PARAMETER;
> - }
> -
> - if (IsListEmpty (&StatementList->StatementList)) {
> - return EFI_SUCCESS;
> - }
> -
> - NextLink = GetFirstNode (&StatementList->StatementList);
> - while (!IsNull (&StatementList->StatementList, NextLink)) {
> - StatementRef =
> REDFISH_PLATFORM_CONFIG_STATEMENT_REF_FROM_LINK (NextLink);
> - NextLink = 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<BR>
> +
> + 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 == NULL || StringId == 0) {
> + DEBUG ((DEBUG_INFO, "???"));
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + String = HiiGetString (HiiHandle, StringId, NULL);
> + if (String == 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 == NULL) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + Index = 0;
> + HiiFormLink = GetFirstNode (&FormsetPrivate->HiiFormList);
> + while (!IsNull (&FormsetPrivate->HiiFormList, HiiFormLink)) {
> + HiiFormPrivate = REDFISH_PLATFORM_CONFIG_FORM_FROM_LINK
> (HiiFormLink);
> + HiiNextFormLink = GetNextNode (&FormsetPrivate->HiiFormList,
> HiiFormLink);
> +
> + DEBUG ((DEBUG_INFO, " [%d] form: %d title: ", ++Index, HiiFormPrivate-
> >Id));
> + DumpHiiString (FormsetPrivate->HiiHandle, HiiFormPrivate->Title);
> + DEBUG ((DEBUG_INFO, "\n"));
> +
> + HiiStatementLink = GetFirstNode (&HiiFormPrivate->StatementList);
> + while (!IsNull (&HiiFormPrivate->StatementList, HiiStatementLink)) {
> + HiiStatementPrivate =
> REDFISH_PLATFORM_CONFIG_STATEMENT_FROM_LINK (HiiStatementLink);
> + HiiNextStatementLink = GetNextNode (&HiiFormPrivate->StatementList,
> HiiStatementLink);
> +
> + DEBUG ((DEBUG_INFO, " QID: 0x%x Prompt: ", HiiStatementPrivate-
> >QuestionId));
> + DumpHiiString (FormsetPrivate->HiiHandle, HiiStatementPrivate-
> >Description);
> + DEBUG ((DEBUG_INFO, "\n"));
> +
> + HiiStatementLink = HiiNextStatementLink;
> + }
> +
> + HiiFormLink = 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 == NULL) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + if (IsListEmpty (FormsetList)) {
> + DEBUG ((DEBUG_INFO, "%a, Empty formset list\n", __FUNCTION__));
> + return EFI_SUCCESS;
> + }
> +
> + Index = 0;
> + HiiFormsetLink = GetFirstNode (FormsetList);
> + while (!IsNull (FormsetList, HiiFormsetLink)) {
> + HiiFormsetNextLink = GetNextNode (FormsetList, HiiFormsetLink);
> + HiiFormsetPrivate =
> REDFISH_PLATFORM_CONFIG_FORMSET_FROM_LINK (HiiFormsetLink);
> +
> + DEBUG ((DEBUG_INFO, "[%d] HII Handle: 0x%x formset: %g at %s\n",
> ++Index, HiiFormsetPrivate->HiiHandle, &HiiFormsetPrivate->Guid,
> HiiFormsetPrivate->DevicePathStr));
> + DumpFormset (HiiFormsetPrivate);
> +
> + HiiFormsetLink = 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 responsible
> + 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 string
> 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 == NULL || HiiHandle ==
> NULL || StringId == 0 || IS_EMPTY_STRING (Language)) {
> + ASSERT (FALSE);
> + return NULL;
> + }
> +
> + //
> + // Retrieve the size of the string in the string package for the BestLanguage
> + //
> + StringSize = 0;
> + Status = 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
> GetString()
> + // returns an error other than EFI_BUFFER_TOO_SMALL, then HiiHandle is
> not present
> + // in the HII Database
> + //
> + if (Status != EFI_BUFFER_TOO_SMALL) {
> + return NULL;
> + }
> +
> + //
> + // Allocate a buffer for the return string
> + //
> + String = AllocateZeroPool (StringSize);
> + if (String == NULL) {
> + return NULL;
> + }
> +
> + //
> + // Retrieve the string from the string package
> + //
> + Status = 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 = NULL;
> + }
> +
> + //
> + // Return the Null-terminated Unicode string
> + //
> + return String;
> +}
> +
> +/**
> + Retrieves a string from a string package in a English language. The
> + returned string is allocated using AllocatePool(). The caller is responsible
> + 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
The function parameters are not correct.
> string
> + package associated with HiiHandle.
> +
> + @retval NULL The string specified by StringId is not present in the string
> 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 = HiiGetRedfishString (HiiHandle, Language, StringId);
> + if (HiiString == NULL) {
> + DEBUG ((DEBUG_ERROR, "%a, Can not find string ID: 0x%x with %a\n",
> __FUNCTION__, StringId, Language));
> + return NULL;
> + }
> +
> + StringSize = (StrLen (HiiString) + 1) * sizeof (CHAR8);
> + AsciiString = AllocatePool (StringSize);
> + if (AsciiString == 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 string
> 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
> otherwise.
> +
> +**/
> +BOOLEAN
> +CheckSupportedSchema (
> + IN REDFISH_PLATFORM_CONFIG_SCHEMA *SupportedSchema,
> + IN CHAR8 *Schema
> + )
> +{
> + UINTN Index;
> +
> + if (SupportedSchema == NULL || IS_EMPTY_STRING (Schema)) {
> + return FALSE;
> + }
> +
> + if (SupportedSchema->Count == 0) {
> + return FALSE;
> + }
> +
> + for (Index = 0; Index < SupportedSchema->Count; Index++) {
> + if (AsciiStrCmp (SupportedSchema->SchemaList[Index], Schema) == 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 NULL.
> + @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 == NULL || SupportedSchema == NULL) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + SupportedSchema->Count = 0;
> +
> + SupportedLanguages = HiiGetSupportedLanguages (HiiHandle);
> + if (SupportedLanguages == NULL) {
> + return EFI_NOT_FOUND;
> + }
> +
> + Index = 0;
> + LangIndex = 0;
> + Count = 0;
> + while (TRUE) {
> + if (SupportedLanguages[Index] == ';' || SupportedLanguages[Index] ==
> '\0') {
> + if (AsciiStrnCmp (&SupportedLanguages[LangIndex],
> X_UEFI_SCHEMA_PREFIX, AsciiStrLen (X_UEFI_SCHEMA_PREFIX)) == 0) {
> + ++Count;
> + }
> + LangIndex = Index + 1;
> + }
> +
> + if (SupportedLanguages[Index] == '\0') {
> + break;
> + }
> +
> + ++Index;
> + }
> +
> + if (Count == 0) {
> + return EFI_NOT_FOUND;
> + }
> +
> + SupportedSchema->Count = Count;
> + SupportedSchema->SchemaList = AllocatePool (sizeof (CHAR8 *) * Count);
> + if (SupportedSchema->SchemaList == NULL) {
> + return EFI_OUT_OF_RESOURCES;
> + }
> +
> + Index = 0;
> + LangIndex = 0;
> + ListIndex = 0;
> + while (TRUE) {
> +
> + if (SupportedLanguages[Index] == ';' || SupportedLanguages[Index] ==
> '\0') {
> + if (AsciiStrnCmp (&SupportedLanguages[LangIndex],
> X_UEFI_SCHEMA_PREFIX, AsciiStrLen (X_UEFI_SCHEMA_PREFIX)) == 0) {
> + StrSize = Index - LangIndex;
> + SupportedSchema->SchemaList[ListIndex] = AllocateCopyPool ((StrSize
> + 1), &SupportedLanguages[LangIndex]);
> + SupportedSchema->SchemaList[ListIndex][StrSize] = '\0';
> + ++ListIndex;
> + }
> +
> + LangIndex = Index + 1;
> + }
> +
> + if (SupportedLanguages[Index] == '\0') {
> + break;
> + }
> +
> + ++Index;
> + }
> +
> + return EFI_SUCCESS;
> +}
> +
> +/**
> + Search and find statement private instance by given regular expression
> patthern
> + 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
> *RegularExpressionProtocol,
> + 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 == NULL || IS_EMPTY_STRING (Schema) ||
> IS_EMPTY_STRING (Pattern) || StatementList == NULL) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + if (RegularExpressionProtocol == NULL) {
> + return EFI_NOT_READY;
> + }
> +
> + StatementList->Count = 0;
> + InitializeListHead (&StatementList->StatementList);
> +
> + if (IsListEmpty (FormsetList)) {
> + return EFI_NOT_FOUND;
> + }
> +
> + HiiFormsetLink = GetFirstNode (FormsetList);
> + while (!IsNull (FormsetList, HiiFormsetLink)) {
> + HiiFormsetNextLink = GetNextNode (FormsetList, HiiFormsetLink);
> + HiiFormsetPrivate =
> REDFISH_PLATFORM_CONFIG_FORMSET_FROM_LINK (HiiFormsetLink);
> +
> + //
> + // Performance check.
> + // If there is no desired Redfish schema found, skip this formset.
> + //
> + if (!CheckSupportedSchema (&HiiFormsetPrivate->SupportedSchema,
> Schema)) {
> + HiiFormsetLink = HiiFormsetNextLink;
> + continue;
> + }
> +
> + HiiFormLink = GetFirstNode (&HiiFormsetPrivate->HiiFormList);
> + while (!IsNull (&HiiFormsetPrivate->HiiFormList, HiiFormLink)) {
> + HiiNextFormLink = GetNextNode (&HiiFormsetPrivate->HiiFormList,
> HiiFormLink);
> + HiiFormPrivate = REDFISH_PLATFORM_CONFIG_FORM_FROM_LINK
> (HiiFormLink);
> +
> + HiiStatementLink =GetFirstNode (&HiiFormPrivate->StatementList);
> + while (!IsNull (&HiiFormPrivate->StatementList, HiiStatementLink)) {
> + HiiNextStatementLink = GetNextNode (&HiiFormPrivate-
> >StatementList, HiiStatementLink);
> + HiiStatementPrivate =
> REDFISH_PLATFORM_CONFIG_STATEMENT_FROM_LINK (HiiStatementLink);
> +
> + if (HiiStatementPrivate->Description != 0) {
> + TmpString = HiiGetRedfishString (HiiFormsetPrivate->HiiHandle,
> Schema, HiiStatementPrivate->Description);
> + if (TmpString != NULL) {
> + Status = RegularExpressionProtocol->MatchString (
> + RegularExpressionProtocol,
> + TmpString,
> + Pattern,
> + &gEfiRegexSyntaxTypePerlGuid,
> + &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 = AllocateZeroPool (sizeof
> (REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_REF));
> + if (StatementRef == NULL) {
> + return EFI_OUT_OF_RESOURCES;
> + }
> +
> + StatementRef->Statement = HiiStatementPrivate;
> + InsertTailList (&StatementList->StatementList, &StatementRef-
> >Link);
> + ++StatementList->Count;
> + }
> +
> + FreePool (TmpString);
> + }
> + }
> +
> + HiiStatementLink = HiiNextStatementLink;
> + }
> +
> + HiiFormLink = HiiNextFormLink;
> + }
> +
> + HiiFormsetLink = 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 statement 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 == NULL || IS_EMPTY_STRING (Schema) ||
> IS_EMPTY_STRING (ConfigureLang)) {
> + return NULL;
> + }
> +
> + if (IsListEmpty (FormsetList)) {
> + return NULL;
> + }
> +
> + HiiFormsetLink = GetFirstNode (FormsetList);
> + while (!IsNull (FormsetList, HiiFormsetLink)) {
> + HiiFormsetNextLink = GetNextNode (FormsetList, HiiFormsetLink);
> + HiiFormsetPrivate =
> REDFISH_PLATFORM_CONFIG_FORMSET_FROM_LINK (HiiFormsetLink);
> +
> + //
> + // Performance check.
> + // If there is no desired Redfish schema found, skip this formset.
> + //
> + if (!CheckSupportedSchema (&HiiFormsetPrivate->SupportedSchema,
> Schema)) {
> + HiiFormsetLink = HiiFormsetNextLink;
> + continue;
> + }
> +
> + HiiFormLink = GetFirstNode (&HiiFormsetPrivate->HiiFormList);
> + while (!IsNull (&HiiFormsetPrivate->HiiFormList, HiiFormLink)) {
> + HiiNextFormLink = GetNextNode (&HiiFormsetPrivate->HiiFormList,
> HiiFormLink);
> + HiiFormPrivate = REDFISH_PLATFORM_CONFIG_FORM_FROM_LINK
> (HiiFormLink);
> +
> + HiiStatementLink =GetFirstNode (&HiiFormPrivate->StatementList);
> + while (!IsNull (&HiiFormPrivate->StatementList, HiiStatementLink)) {
> + HiiNextStatementLink = GetNextNode (&HiiFormPrivate-
> >StatementList, HiiStatementLink);
> + HiiStatementPrivate =
> REDFISH_PLATFORM_CONFIG_STATEMENT_FROM_LINK (HiiStatementLink);
> +
> + DEBUG_CODE (
> + STATIC UINTN Index = 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 != 0) {
> + TmpString = HiiGetRedfishString (HiiFormsetPrivate->HiiHandle,
> Schema, HiiStatementPrivate->Description);
> + if (TmpString != NULL) {
> + if (StrCmp (TmpString, ConfigureLang) == 0) {
> + FreePool (TmpString);
> + return HiiStatementPrivate;
> + }
> +
> + FreePool (TmpString);
> + }
> + }
> +
> + HiiStatementLink = HiiNextStatementLink;
> + }
> +
> + HiiFormLink = HiiNextFormLink;
> + }
> +
> + HiiFormsetLink = 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 == NULL || FormsetList == NULL) {
> + return NULL;
> + }
> +
> + if (IsListEmpty (FormsetList)) {
> + return NULL;
> + }
> +
> + HiiFormsetLink = GetFirstNode (FormsetList);
> + while (!IsNull (FormsetList, HiiFormsetLink)) {
> + HiiFormsetNextLink = GetNextNode (FormsetList, HiiFormsetLink);
> + HiiFormsetPrivate =
> REDFISH_PLATFORM_CONFIG_FORMSET_FROM_LINK (HiiFormsetLink);
> +
> + if (HiiFormsetPrivate->HiiHandle == HiiHandle) {
> + return HiiFormsetPrivate;
> + }
> +
> + HiiFormsetLink = HiiFormsetNextLink;
> + }
> +
> + return NULL;
> +}
> +
> +/**
> + Release formset and all the forms and statements that belong to this
> formset.
> +
> + @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 == NULL) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + HiiFormLink = GetFirstNode (&FormsetPrivate->HiiFormList);
> + while (!IsNull (&FormsetPrivate->HiiFormList, HiiFormLink)) {
> + HiiFormPrivate = REDFISH_PLATFORM_CONFIG_FORM_FROM_LINK
> (HiiFormLink);
> + HiiNextFormLink = GetNextNode (&FormsetPrivate->HiiFormList,
> HiiFormLink);
> +
> + HiiStatementLink = GetFirstNode (&HiiFormPrivate->StatementList);
> + while (!IsNull (&HiiFormPrivate->StatementList, HiiStatementLink)) {
> + HiiStatementPrivate =
> REDFISH_PLATFORM_CONFIG_STATEMENT_FROM_LINK (HiiStatementLink);
> + HiiNextStatementLink = GetNextNode (&HiiFormPrivate->StatementList,
> HiiStatementLink);
> +
> + //
> + // HiiStatementPrivate->HiiStatement will be released in
> DestroyFormSet().
> + //
> +
> + if (HiiStatementPrivate->DesStringCache != NULL) {
> + FreePool (HiiStatementPrivate->DesStringCache);
> + HiiStatementPrivate->DesStringCache = NULL;
> + }
> +
> + RemoveEntryList (&HiiStatementPrivate->Link);
> + FreePool (HiiStatementPrivate);
> + HiiStatementLink = HiiNextStatementLink;
> + }
> +
> + //
> + // HiiStatementPrivate->HiiForm will be released in DestroyFormSet().
> + //
> +
> + RemoveEntryList (&HiiFormPrivate->Link);
> + FreePool (HiiFormPrivate);
> + HiiFormLink = HiiNextFormLink;
> + }
> +
> + if (FormsetPrivate->HiiFormSet != NULL) {
> + DestroyFormSet (FormsetPrivate->HiiFormSet);
> + FormsetPrivate->HiiFormSet = NULL;
> + }
> +
> + if (FormsetPrivate->DevicePathStr != NULL) {
> + FreePool(FormsetPrivate->DevicePathStr);
> + }
> +
> + //
> + // Release schema list
> + //
> + if (FormsetPrivate->SupportedSchema.SchemaList != NULL) {
> + for (Index = 0; Index < FormsetPrivate->SupportedSchema.Count;
> Index++) {
> + FreePool (FormsetPrivate->SupportedSchema.SchemaList[Index]);
> + }
> +
> + FreePool (FormsetPrivate->SupportedSchema.SchemaList);
> + FormsetPrivate->SupportedSchema.SchemaList = NULL;
> + FormsetPrivate->SupportedSchema.Count = 0;
> + }
> +
> + return EFI_SUCCESS;
> +}
> +
> +/**
> + Create new form-set instance.
> +
> + @retval REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE * Pointer to
> newly created form-set private instance.
> +
> +**/
> +REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *
> +NewFormsetPrivate (
> + VOID
> + )
> +{
> + REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *NewFormsetPrivate;
> +
> + NewFormsetPrivate = AllocateZeroPool (sizeof
> (REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE));
> + if (NewFormsetPrivate == 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 == NULL || FormsetPrivate == NULL) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> +
> + HiiFormSet = AllocateZeroPool (sizeof (HII_FORMSET));
> + if (HiiFormSet == NULL) {
> + return EFI_OUT_OF_RESOURCES;
> + }
> +
> + //
> + // Find HII formset by the given HII handle.
> + //
> + ZeroMem (&ZeroGuid, sizeof (ZeroGuid));
> + Status = CreateFormSetFromHiiHandle (HiiHandle, &ZeroGuid, HiiFormSet);
> + if (EFI_ERROR (Status) || IsListEmpty (&HiiFormSet->FormListHead)) {
> + Status = EFI_NOT_FOUND;
> + goto ErrorExit;
> + }
> +
> + //
> + // Initialize formset
> + //
> + InitializeFormSet (HiiFormSet);
> +
> + //
> + // Initialize formset private data.
> + //
> + FormsetPrivate->HiiFormSet = HiiFormSet;
> + FormsetPrivate->HiiHandle = HiiHandle;
> + CopyGuid (&FormsetPrivate->Guid, &HiiFormSet->Guid);
> + FormsetPrivate->DevicePathStr = ConvertDevicePathToText (HiiFormSet-
> >DevicePath, FALSE, FALSE);
> + Status = GetSupportedSchema (FormsetPrivate->HiiHandle,
> &FormsetPrivate->SupportedSchema);
> + if (EFI_ERROR (Status)) {
> + DEBUG ((DEBUG_WARN, "%a, No schema from HII handle: 0x%x found:
> %r\n", __FUNCTION__, FormsetPrivate->HiiHandle, Status));
> + }
> +
> + HiiFormLink = GetFirstNode (&HiiFormSet->FormListHead);
> + while (!IsNull (&HiiFormSet->FormListHead, HiiFormLink)) {
> + HiiForm = HII_FORM_FROM_LINK (HiiFormLink);
> +
> + HiiFormPrivate = AllocateZeroPool (sizeof
> (REDFISH_PLATFORM_CONFIG_FORM_PRIVATE));
> + if (HiiFormPrivate == NULL) {
> + Status = EFI_OUT_OF_RESOURCES;
> + goto ErrorExit;
> + }
> +
> + //
> + // Initialize form private data.
> + //
> + HiiFormPrivate->HiiForm = HiiForm;
> + HiiFormPrivate->Id = HiiForm->FormId;
> + HiiFormPrivate->Title = HiiForm->FormTitle;
> + HiiFormPrivate->ParentFormset = FormsetPrivate;
> + InitializeListHead (&HiiFormPrivate->StatementList);
> +
> + HiiStatementLink = GetFirstNode (&HiiForm->StatementListHead);
> + while (!IsNull (&HiiForm->StatementListHead, HiiStatementLink)) {
> + HiiStatement = HII_STATEMENT_FROM_LINK (HiiStatementLink);
> +
> + HiiStatementPrivate = AllocateZeroPool (sizeof
> (REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE));
> + if (HiiStatementPrivate == NULL) {
> + Status = EFI_OUT_OF_RESOURCES;
> + goto ErrorExit;
> + }
> + //
> + // Initialize statement private data.
> + //
> + HiiStatementPrivate->HiiStatement = HiiStatement;
> + HiiStatementPrivate->QuestionId = HiiStatement->QuestionId;
> + HiiStatementPrivate->Description = HiiStatement->Prompt;
> + HiiStatementPrivate->ParentForm = HiiFormPrivate;
> +
> + //
> + // Attach to statement list.
> + //
> + InsertTailList (&HiiFormPrivate->StatementList, &HiiStatementPrivate-
> >Link);
> + HiiStatementLink = GetNextNode (&HiiForm->StatementListHead,
> HiiStatementLink);
> + }
> + //
> + // Attach to form list.
> + //
> + InsertTailList (&FormsetPrivate->HiiFormList, &HiiFormPrivate->Link);
> + HiiFormLink = GetNextNode (&HiiFormSet->FormListHead, HiiFormLink);
> + }
> +
> + return EFI_SUCCESS;
> +
> +ErrorExit:
> +
> + //
> + // Release HiiFormSet if HiiFormSet is not linked to FormsetPrivate yet.
> + //
> + if (HiiFormSet != NULL && FormsetPrivate->HiiFormSet != 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 == NULL || FormsetList == NULL) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + FormsetPrivate = GetFormsetPrivateByHiiHandle (HiiHandle, FormsetList);
> + if (FormsetPrivate != NULL) {
> + return EFI_ALREADY_STARTED;
> + }
> +
> + FormsetPrivate = NewFormsetPrivate ();
> + if (FormsetPrivate == NULL) {
> + DEBUG ((DEBUG_ERROR, "%a, out of resource\n", __FUNCTION__));
> + return EFI_OUT_OF_RESOURCES;
> + }
> +
> + //
> + // Load formset on the given HII handle.
> + //
> + Status = 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 == NULL) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + if (IsListEmpty (FormsetList)) {
> + return EFI_SUCCESS;
> + }
> +
> + HiiFormsetLink = GetFirstNode (FormsetList);
> + while (!IsNull (FormsetList, HiiFormsetLink)) {
> + HiiFormsetNextLink = GetNextNode (FormsetList, HiiFormsetLink);
> + HiiFormsetPrivate =
> REDFISH_PLATFORM_CONFIG_FORMSET_FROM_LINK (HiiFormsetLink);
> +
> + //
> + // Detach from list.
> + //
> + RemoveEntryList (&HiiFormsetPrivate->Link);
> + ReleaseFormset (HiiFormsetPrivate);
> + FreePool (HiiFormsetPrivate);
> + HiiFormsetLink = 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 == NULL || PendingList == NULL) {
> + return NULL;
> + }
> +
> + if (IsListEmpty (PendingList)) {
> + return NULL;
> + }
> +
> + PendingListLink = GetFirstNode (PendingList);
> + while (!IsNull (PendingList, PendingListLink)) {
> + Target = REDFISH_PLATFORM_CONFIG_PENDING_LIST_FROM_LINK
> (PendingListLink);
> +
> + if (Target->HiiHandle == HiiHandle) {
> + return Target;
> + }
> +
> + PendingListLink = 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 recently
> 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 == NULL || PendingList == NULL) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + //
> + // Check and see if this HII handle is processed already.
> + //
> + TargetPendingList = GetPendingList (HiiHandle, PendingList);
> + if (TargetPendingList != NULL) {
> + TargetPendingList->IsDeleted = FALSE;
> + DEBUG_CODE (
> + DEBUG ((DEBUG_INFO, "%a, HII handle: 0x%x is updated\n",
> __FUNCTION__, HiiHandle));
> + );
> + return EFI_SUCCESS;
> + }
> +
> + TargetPendingList= AllocateZeroPool (sizeof
> (REDFISH_PLATFORM_CONFIG_PENDING_LIST));
> + if (TargetPendingList == NULL) {
> + return EFI_OUT_OF_RESOURCES;
> + }
> +
> + TargetPendingList->HiiHandle = HiiHandle;
> + TargetPendingList->IsDeleted = 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
> 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 recently
> 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 == NULL || PendingList == NULL) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + //
> + // Check and see if this HII handle is processed already.
> + //
> + TargetPendingList = GetPendingList (HiiHandle, PendingList);
> + if (TargetPendingList != NULL) {
> + TargetPendingList->IsDeleted = TRUE;
> + DEBUG_CODE (
> + DEBUG ((DEBUG_INFO, "%a, HII handle: 0x%x is updated and deleted\n",
> __FUNCTION__, HiiHandle));
> + );
> + return EFI_SUCCESS;
> + }
> +
> + TargetPendingList= AllocateZeroPool (sizeof
> (REDFISH_PLATFORM_CONFIG_PENDING_LIST));
> + if (TargetPendingList == NULL) {
> + return EFI_OUT_OF_RESOURCES;
> + }
> +
> + TargetPendingList->HiiHandle = HiiHandle;
> + TargetPendingList->IsDeleted = 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
> NULL.
> +
> +**/
> +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 == NULL || PendingList == NULL) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + if (IsListEmpty (PendingList)) {
> + return EFI_SUCCESS;
> + }
> +
> + PendingListLink = GetFirstNode (PendingList);
> + while (!IsNull (PendingList, PendingListLink)) {
> + PendingListNextLink = GetNextNode (PendingList, PendingListLink);
> + Target = REDFISH_PLATFORM_CONFIG_PENDING_LIST_FROM_LINK
> (PendingListLink);
> +
> + if (Target->IsDeleted) {
> + //
> + // The HII resource on this HII handle is removed. Release the formset.
> + //
> + FormsetPrivate = GetFormsetPrivateByHiiHandle (Target->HiiHandle,
> FormsetList);
> + if (FormsetPrivate != NULL) {
> + DEBUG ((DEBUG_INFO, "%a, formset: %g is removed because driver
> release 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 already\n", __FUNCTION__, Target->HiiHandle));
> + }
> + } else {
> + //
> + // The HII resource on this HII handle is updated/removed.
> + //
> + FormsetPrivate = GetFormsetPrivateByHiiHandle (Target->HiiHandle,
> FormsetList);
> + if (FormsetPrivate != NULL) {
> + //
> + // HII formset already exist, release it and query again.
> + //
> + DEBUG ((DEBUG_INFO, "%a, formset: %g is updated. Release current
> formset\n", __FUNCTION__, &FormsetPrivate->Guid));
> + RemoveEntryList (&FormsetPrivate->Link);
> + ReleaseFormset (FormsetPrivate);
> + FreePool (FormsetPrivate);
> + }
> +
> + Status = LoadFormsetList (Target->HiiHandle, FormsetList);
> + if (EFI_ERROR (Status)) {
> + DEBUG ((DEBUG_ERROR, "%a, load formset from HII handle: 0x%x
> failed: %r\n", __FUNCTION__, Target->HiiHandle, Status));
> + }
> + }
> +
> + //
> + // Detach it from list first.
> + //
> + RemoveEntryList (&Target->Link);
> + FreePool (Target);
> +
> + PendingListLink = 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 == NULL) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + if (IsListEmpty (&StatementList->StatementList)) {
> + return EFI_SUCCESS;
> + }
> +
> + NextLink = GetFirstNode (&StatementList->StatementList);
> + while (!IsNull (&StatementList->StatementList, NextLink)) {
> + StatementRef =
> REDFISH_PLATFORM_CONFIG_STATEMENT_REF_FROM_LINK (NextLink);
> + NextLink = 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..be2f63df8d 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<BR>
> -
> - SPDX-License-Identifier: BSD-2-Clause-Patent
> -
> -**/
> -
> -#ifndef EDKII_REDFISH_PLATFORM_CONFIG_IMPL_H_
> -#define EDKII_REDFISH_PLATFORM_CONFIG_IMPL_H_
> -
> -#include <Uefi.h>
> -
> -//
> -// Libraries
> -//
> -#include <Library/BaseLib.h>
> -#include <Library/BaseMemoryLib.h>
> -#include <Library/DebugLib.h>
> -#include <Library/DevicePathLib.h>
> -#include <Library/HiiUtilityLib.h>
> -#include <Library/HiiLib.h>
> -#include <Library/MemoryAllocationLib.h>
> -#include <Library/UefiBootServicesTableLib.h>
> -#include <Library/UefiLib.h>
> -
> -#define REDFISH_PLATFORM_CONFIG_DELETE_EXPIRED_FORMSET 0x00
> -#define IS_EMPTY_STRING(a) (a == NULL || a[0] == 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, REDFISH_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 formset data.
> - EFI_GUID Guid; // Formset GUID.
> - EFI_HII_HANDLE HiiHandle; // Hii Handle of this formset.
> - 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 supported 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 token of form title.
> - REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *ParentFormset;
> - HII_FORM *HiiForm; // Pointer to HII form data.
> - LIST_ENTRY StatementList; // Statement list that keep
> statement under this form.
> -} REDFISH_PLATFORM_CONFIG_FORM_PRIVATE;
> -
> -#define REDFISH_PLATFORM_CONFIG_FORM_FROM_LINK(a) BASE_CR (a,
> REDFISH_PLATFORM_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 cache for search
> function.
> -} REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE;
> -
> -#define REDFISH_PLATFORM_CONFIG_STATEMENT_FROM_LINK(a)
> BASE_CR (a, REDFISH_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, REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_REF, Link)
> -
> -//
> -// Definition of REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_LIST
> -//
> -typedef struct {
> - LIST_ENTRY StatementList; // List of
> REDFISH_PLATFORM_CONFIG_STATEMENT_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 recently
> 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
> 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 recently
> 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
> statement 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
> patthern
> - 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
> *RegularExpressionProtocol,
> - 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
> NULL.
> -
> -**/
> -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 responsible
> - 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 string
> 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<BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef EDKII_REDFISH_PLATFORM_CONFIG_IMPL_H_
> +#define EDKII_REDFISH_PLATFORM_CONFIG_IMPL_H_
> +
> +#include <Uefi.h>
> +
> +//
> +// Libraries
> +//
> +#include <Library/BaseLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/DevicePathLib.h>
> +#include <Library/HiiUtilityLib.h>
> +#include <Library/HiiLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/UefiLib.h>
> +
> +#define IS_EMPTY_STRING(a) (a == NULL || a[0] == 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, REDFISH_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 formset data.
> + EFI_GUID Guid; // Formset GUID.
> + EFI_HII_HANDLE HiiHandle; // Hii Handle of this formset.
> + 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 supported 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 token of form title.
> + REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *ParentFormset;
> + HII_FORM *HiiForm; // Pointer to HII form data.
> + LIST_ENTRY StatementList; // Statement list that keep
> statement under this form.
> +} REDFISH_PLATFORM_CONFIG_FORM_PRIVATE;
> +
> +#define REDFISH_PLATFORM_CONFIG_FORM_FROM_LINK(a) BASE_CR (a,
> REDFISH_PLATFORM_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 cache for search
> function.
> +} REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE;
> +
> +#define REDFISH_PLATFORM_CONFIG_STATEMENT_FROM_LINK(a)
> BASE_CR (a, REDFISH_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, REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_REF, Link)
> +
> +//
> +// Definition of REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_LIST
> +//
> +typedef struct {
> + LIST_ENTRY StatementList; // List of
> REDFISH_PLATFORM_CONFIG_STATEMENT_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 recently
> 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
> 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 recently
> 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 statement 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
> patthern
> + 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
> *RegularExpressionProtocol,
> + 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
> NULL.
> +
> +**/
> +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 responsible
> + 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 string
> 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 string from a string package in a English language. The
> + returned string is allocated using AllocatePool(). The caller is responsible
> + 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
The function parameters are not correct.
Thanks
Abner
> + package associated with HiiHandle.
> +
> + @retval NULL The string specified by StringId is not present in the string
> 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
> --
> 2.32.0.windows.2
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2022-07-25 3:29 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-07-24 13:19 [edk2-staging][PATCH v2 1/1] edk2/RedfishPkg: Update Redfish Platform Config Protocol Nickle Wang
2022-07-24 13:46 ` Chang, Abner
2022-07-25 3:25 ` Nickle Wang
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox