[AMD Official Use Only - General]
Hi Nickle, I found there are many redundant blank lines in the patch. Could you please check it?
Thanks Abner
toggle quoted messageShow quoted text
-----Original Message----- From: Nickle Wang <nickle.wang@...> Sent: Tuesday, July 12, 2022 8:20 PM To: devel@edk2.groups.io Cc: Chang, Abner <Abner.Chang@...>; Yang, Atom <Atom.Yang@...>; Nick Ramirez <nramirez@...> Subject: [edk2][PATCH] 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@...> Cc: Abner Chang <abner.chang@...> Cc: Yang Atom <Atom.Yang@...> Cc: Nick Ramirez <nramirez@...> --- .../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
|