diff --git a/RedfishClientPkg/Features/Bios/v1_0_9/Common/BiosCommon.c b/RedfishClientPkg/Features/Bios/v1_0_9/Common/BiosCommon.c
index f96c90cc9..3b6eab3fd 100644
--- a/RedfishClientPkg/Features/Bios/v1_0_9/Common/BiosCommon.c
+++ b/RedfishClientPkg/Features/Bios/v1_0_9/Common/BiosCommon.c
@@ -267,18 +267,22 @@ ProvisioningBiosResource (
IN EFI_STRING ConfigureLang
)
{
- CHAR8 *Json;
- CHAR8 *JsonWithAddendum;
- EFI_STATUS Status;
- EFI_STRING NewResourceLocation;
- CHAR8 *EtagStr;
- CHAR8 ResourceId[16];
+ CHAR8 *Json;
+ CHAR8 *JsonWithAddendum;
+ EFI_STATUS Status;
+ EFI_STRING NewResourceLocation;
+ CHAR8 *EtagStr;
+ CHAR8 ResourceId[16];
+ REDFISH_RESPONSE Response;
if (IS_EMPTY_STRING (ConfigureLang) || (Private == NULL)) {
return EFI_INVALID_PARAMETER;
}
- EtagStr = NULL;
+ EtagStr = NULL;
+ Json = NULL;
+ NewResourceLocation = NULL;
+ ZeroMem (&Response, sizeof (REDFISH_RESPONSE));
AsciiSPrint (ResourceId, sizeof (ResourceId), "%d", Index);
Status = ProvisioningBiosProperties (
@@ -326,19 +330,25 @@ ProvisioningBiosResource (
JsonWithAddendum = NULL;
}
- Status = CreatePayloadToPostResource (Private->RedfishService, Private->Payload, Json, &NewResourceLocation, &EtagStr);
+ Status = RedfishHttpPostResource (Private->RedfishService, Private->Uri, Json, &Response);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "%a, post Bios resource for %s failed: %r\n", __func__, ConfigureLang, Status));
goto RELEASE_RESOURCE;
}
+ Status = GetEtagAndLocation (&Response, &EtagStr, &NewResourceLocation);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a, get ETag and location failed: %r\n", __func__, Status));
+ goto RELEASE_RESOURCE;
+ }
+
ASSERT (NewResourceLocation != NULL);
//
// Keep location of new resource.
//
if (NewResourceLocation != NULL) {
- RedfisSetRedfishUri (ConfigureLang, NewResourceLocation);
+ RedfishSetRedfishUri (ConfigureLang, NewResourceLocation);
}
//
@@ -359,6 +369,8 @@ ProvisioningBiosResource (
FreePool (Json);
}
+ RedfishHttpFreeResource (&Response);
+
return Status;
}
@@ -401,11 +413,12 @@ ProvisioningBiosExistResource (
IN REDFISH_RESOURCE_COMMON_PRIVATE *Private
)
{
- EFI_STATUS Status;
- EFI_STRING ConfigureLang;
- CHAR8 *EtagStr;
- CHAR8 *Json;
- CHAR8 *JsonWithAddendum;
+ EFI_STATUS Status;
+ EFI_STRING ConfigureLang;
+ CHAR8 *EtagStr;
+ CHAR8 *Json;
+ CHAR8 *JsonWithAddendum;
+ REDFISH_RESPONSE Response;
if (Private == NULL) {
return EFI_INVALID_PARAMETER;
@@ -414,6 +427,7 @@ ProvisioningBiosExistResource (
EtagStr = NULL;
Json = NULL;
ConfigureLang = NULL;
+ ZeroMem (&Response, sizeof (REDFISH_RESPONSE));
ConfigureLang = RedfishGetConfigLanguage (Private->Uri);
if (ConfigureLang == NULL) {
@@ -472,13 +486,19 @@ ProvisioningBiosExistResource (
DEBUG ((REDFISH_DEBUG_TRACE, "%a, provisioning existing resource for %s\n", __func__, ConfigureLang));
//
- // PUT back to instance
+ // PATCH back to instance
//
- Status = CreatePayloadToPatchResource (Private->RedfishService, Private->Payload, Json, &EtagStr);
+ Status = RedfishHttpPatchResource (Private->RedfishService, Private->Uri, Json, &Response);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "%a, patch resource for %s failed: %r\n", __func__, ConfigureLang, Status));
}
+ Status = GetEtagAndLocation (&Response, &EtagStr, NULL);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a, get ETag failed: %r\n", __func__, Status));
+ goto ON_RELEASE;
+ }
+
//
// Handle Etag
//
@@ -497,6 +517,8 @@ ProvisioningBiosExistResource (
FreePool (ConfigureLang);
}
+ RedfishHttpFreeResource (&Response);
+
return Status;
}
@@ -595,11 +617,12 @@ RedfishUpdateResourceCommon (
IN CHAR8 *InputJson
)
{
- EFI_STATUS Status;
- CHAR8 *Json;
- CHAR8 *JsonWithAddendum;
- EFI_STRING ConfigureLang;
- CHAR8 *EtagStr;
+ EFI_STATUS Status;
+ CHAR8 *Json;
+ CHAR8 *JsonWithAddendum;
+ EFI_STRING ConfigureLang;
+ CHAR8 *EtagStr;
+ REDFISH_RESPONSE Response;
if ((Private == NULL) || IS_EMPTY_STRING (InputJson)) {
return EFI_INVALID_PARAMETER;
@@ -608,6 +631,7 @@ RedfishUpdateResourceCommon (
EtagStr = NULL;
Json = NULL;
ConfigureLang = NULL;
+ ZeroMem (&Response, sizeof (REDFISH_RESPONSE));
ConfigureLang = RedfishGetConfigLanguage (Private->Uri);
if (ConfigureLang == NULL) {
@@ -666,13 +690,19 @@ RedfishUpdateResourceCommon (
DEBUG ((REDFISH_DEBUG_TRACE, "%a, update resource for %s\n", __func__, ConfigureLang));
//
- // PUT back to instance
+ // PATCH back to instance
//
- Status = CreatePayloadToPatchResource (Private->RedfishService, Private->Payload, Json, &EtagStr);
+ Status = RedfishHttpPatchResource (Private->RedfishService, Private->Uri, Json, &Response);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "%a, patch resource for %s failed: %r\n", __func__, ConfigureLang, Status));
}
+ Status = GetEtagAndLocation (&Response, &EtagStr, NULL);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a, get ETag failed: %r\n", __func__, Status));
+ goto ON_RELEASE;
+ }
+
//
// Handle Etag
//
@@ -691,6 +721,8 @@ RedfishUpdateResourceCommon (
FreePool (ConfigureLang);
}
+ RedfishHttpFreeResource (&Response);
+
return Status;
}
@@ -745,7 +777,7 @@ RedfishIdentifyResourceCommon (
//
// Keep URI and ConfigLang mapping
//
- RedfisSetRedfishUri (ConfigLangList.List[0].ConfigureLang, Private->Uri);
+ RedfishSetRedfishUri (ConfigLangList.List[0].ConfigureLang, Private->Uri);
//
// Set the configuration language in the RESOURCE_INFORMATION_EXCHANGE.
// This information is sent back to the parent resource (e.g. the collection driver).
diff --git a/RedfishClientPkg/Features/Bios/v1_0_9/Dxe/BiosDxe.c b/RedfishClientPkg/Features/Bios/v1_0_9/Dxe/BiosDxe.c
index 9b336d3de..ee294c4bb 100644
--- a/RedfishClientPkg/Features/Bios/v1_0_9/Dxe/BiosDxe.c
+++ b/RedfishClientPkg/Features/Bios/v1_0_9/Dxe/BiosDxe.c
@@ -56,7 +56,8 @@ RedfishResourceProvisioningResource (
return EFI_NOT_READY;
}
- Status = GetResourceByUri (Private->RedfishService, Uri, &Response);
+ ZeroMem (&Response, sizeof (Response));
+ Status = RedfishHttpGetResource (Private->RedfishService, Uri, &Response, TRUE);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "%a, get resource from: %s failed\n", __func__, Uri));
return Status;
@@ -72,12 +73,7 @@ RedfishResourceProvisioningResource (
// Release resource
//
if (Private->Payload != NULL) {
- RedfishFreeResponse (
- Response.StatusCode,
- Response.HeaderCount,
- Response.Headers,
- Response.Payload
- );
+ RedfishHttpFreeResource (&Response);
Private->Payload = NULL;
}
@@ -122,7 +118,8 @@ RedfishResourceConsumeResource (
return EFI_NOT_READY;
}
- Status = GetResourceByUri (Private->RedfishService, Uri, &Response);
+ ZeroMem (&Response, sizeof (Response));
+ Status = RedfishHttpGetResource (Private->RedfishService, Uri, &Response, TRUE);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "%a, get resource from: %s failed\n", __func__, Uri));
return Status;
@@ -151,7 +148,7 @@ RedfishResourceConsumeResource (
//
RedfishSettingsUri = JsonValueGetUnicodeString (JsonValue);
- Status = GetResourceByUri (Private->RedfishService, RedfishSettingsUri, &RedfishSettingsResponse);
+ Status = RedfishHttpGetResource (Private->RedfishService, RedfishSettingsUri, &RedfishSettingsResponse, TRUE);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "%a, @Redfish.Settings exists, get resource from: %s failed\n", __FUNCTION__, RedfishSettingsUri));
} else {
@@ -195,21 +192,11 @@ RedfishResourceConsumeResource (
//
if (Private->Payload != NULL) {
if (Response.Payload != NULL) {
- RedfishFreeResponse (
- Response.StatusCode,
- Response.HeaderCount,
- Response.Headers,
- Response.Payload
- );
+ RedfishHttpFreeResource (&Response);
}
if (RedfishSettingsResponse.Payload != NULL) {
- RedfishFreeResponse (
- RedfishSettingsResponse.StatusCode,
- RedfishSettingsResponse.HeaderCount,
- RedfishSettingsResponse.Headers,
- RedfishSettingsResponse.Payload
- );
+ RedfishHttpFreeResource (&RedfishSettingsResponse);
}
Private->Payload = NULL;
@@ -290,7 +277,8 @@ RedfishResourceUpdate (
return EFI_NOT_READY;
}
- Status = GetResourceByUri (Private->RedfishService, Uri, &Response);
+ ZeroMem (&Response, sizeof (Response));
+ Status = RedfishHttpGetResource (Private->RedfishService, Uri, &Response, TRUE);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "%a, get resource from: %s failed\n", __func__, Uri));
return Status;
@@ -312,12 +300,7 @@ RedfishResourceUpdate (
// Release resource
//
if (Private->Payload != NULL) {
- RedfishFreeResponse (
- Response.StatusCode,
- Response.HeaderCount,
- Response.Headers,
- Response.Payload
- );
+ RedfishHttpFreeResource (&Response);
Private->Payload = NULL;
}
@@ -360,7 +343,8 @@ RedfishResourceCheck (
return EFI_NOT_READY;
}
- Status = GetResourceByUri (Private->RedfishService, Uri, &Response);
+ ZeroMem (&Response, sizeof (Response));
+ Status = RedfishHttpGetResource (Private->RedfishService, Uri, &Response, TRUE);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "%a, get resource from: %s failed\n", __func__, Uri));
return Status;
@@ -382,12 +366,7 @@ RedfishResourceCheck (
// Release resource
//
if (Private->Payload != NULL) {
- RedfishFreeResponse (
- Response.StatusCode,
- Response.HeaderCount,
- Response.Headers,
- Response.Payload
- );
+ RedfishHttpFreeResource (&Response);
Private->Payload = NULL;
}
@@ -431,7 +410,8 @@ RedfishResourceIdentify (
return EFI_NOT_READY;
}
- Status = GetResourceByUri (Private->RedfishService, Uri, &Response);
+ ZeroMem (&Response, sizeof (Response));
+ Status = RedfishHttpGetResource (Private->RedfishService, Uri, &Response, TRUE);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "%a, get resource from: %s failed\n", __func__, Uri));
return Status;
@@ -453,12 +433,7 @@ RedfishResourceIdentify (
// Release resource
//
if (Private->Payload != NULL) {
- RedfishFreeResponse (
- Response.StatusCode,
- Response.HeaderCount,
- Response.Headers,
- Response.Payload
- );
+ RedfishHttpFreeResource (&Response);
Private->Payload = NULL;
}
diff --git a/RedfishClientPkg/Features/Bios/v1_0_9/Dxe/BiosDxe.inf b/RedfishClientPkg/Features/Bios/v1_0_9/Dxe/BiosDxe.inf
index 37346e50f..dbb032923 100644
--- a/RedfishClientPkg/Features/Bios/v1_0_9/Dxe/BiosDxe.inf
+++ b/RedfishClientPkg/Features/Bios/v1_0_9/Dxe/BiosDxe.inf
@@ -39,6 +39,7 @@
UefiLib
UefiDriverEntryPoint
RedfishAddendumLib
+ RedfishHttpLib
[Protocols]
gEdkIIRedfishConfigHandlerProtocolGuid ## PRODUCED
diff --git a/RedfishClientPkg/Features/ComputerSystem/v1_5_0/Common/ComputerSystemCommon.c b/RedfishClientPkg/Features/ComputerSystem/v1_5_0/Common/ComputerSystemCommon.c
index 7ed1bd55e..4f0a81aec 100644
--- a/RedfishClientPkg/Features/ComputerSystem/v1_5_0/Common/ComputerSystemCommon.c
+++ b/RedfishClientPkg/Features/ComputerSystem/v1_5_0/Common/ComputerSystemCommon.c
@@ -2,6 +2,7 @@
Redfish feature driver implementation - common functions
(C) Copyright 2020-2022 Hewlett Packard Enterprise Development LP
+ Copyright (c) 2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -1236,17 +1237,21 @@ ProvisioningComputerSystemResource (
IN EFI_STRING ConfigureLang
)
{
- CHAR8 *Json;
- EFI_STATUS Status;
- EFI_STRING NewResourceLocation;
- CHAR8 *EtagStr;
- CHAR8 ResourceId[16];
+ CHAR8 *Json;
+ EFI_STATUS Status;
+ EFI_STRING NewResourceLocation;
+ CHAR8 *EtagStr;
+ CHAR8 ResourceId[16];
+ REDFISH_RESPONSE Response;
if (IS_EMPTY_STRING (ConfigureLang) || (Private == NULL)) {
return EFI_INVALID_PARAMETER;
}
- EtagStr = NULL;
+ EtagStr = NULL;
+ Json = NULL;
+ NewResourceLocation = NULL;
+ ZeroMem (&Response, sizeof (REDFISH_RESPONSE));
AsciiSPrint (ResourceId, sizeof (ResourceId), "%d", Index);
Status = ProvisioningComputerSystemProperties (
@@ -1262,19 +1267,25 @@ ProvisioningComputerSystemResource (
return Status;
}
- Status = CreatePayloadToPostResource (Private->RedfishService, Private->Payload, Json, &NewResourceLocation, &EtagStr);
+ Status = RedfishHttpPostResource (Private->RedfishService, Private->Uri, Json, &Response);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "%a, post ComputerSystem resource for %s failed: %r\n", __func__, ConfigureLang, Status));
goto RELEASE_RESOURCE;
}
+ Status = GetEtagAndLocation (&Response, &EtagStr, &NewResourceLocation);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a, get ETag and location failed: %r\n", __func__, Status));
+ goto RELEASE_RESOURCE;
+ }
+
ASSERT (NewResourceLocation != NULL);
//
// Keep location of new resource.
//
if (NewResourceLocation != NULL) {
- RedfisSetRedfishUri (ConfigureLang, NewResourceLocation);
+ RedfishSetRedfishUri (ConfigureLang, NewResourceLocation);
}
//
@@ -1295,6 +1306,8 @@ ProvisioningComputerSystemResource (
FreePool (Json);
}
+ RedfishHttpFreeResource (&Response);
+
return Status;
}
@@ -1337,10 +1350,11 @@ ProvisioningComputerSystemExistResource (
IN REDFISH_RESOURCE_COMMON_PRIVATE *Private
)
{
- EFI_STATUS Status;
- EFI_STRING ConfigureLang;
- CHAR8 *EtagStr;
- CHAR8 *Json;
+ EFI_STATUS Status;
+ EFI_STRING ConfigureLang;
+ CHAR8 *EtagStr;
+ CHAR8 *Json;
+ REDFISH_RESPONSE Response;
if (Private == NULL) {
return EFI_INVALID_PARAMETER;
@@ -1349,6 +1363,7 @@ ProvisioningComputerSystemExistResource (
EtagStr = NULL;
Json = NULL;
ConfigureLang = NULL;
+ ZeroMem (&Response, sizeof (REDFISH_RESPONSE));
ConfigureLang = RedfishGetConfigLanguage (Private->Uri);
if (ConfigureLang == NULL) {
@@ -1375,13 +1390,19 @@ ProvisioningComputerSystemExistResource (
DEBUG ((REDFISH_DEBUG_TRACE, "%a, provisioning existing resource for %s\n", __func__, ConfigureLang));
//
- // PUT back to instance
+ // PATCH back to instance
//
- Status = CreatePayloadToPatchResource (Private->RedfishService, Private->Payload, Json, &EtagStr);
+ Status = RedfishHttpPatchResource (Private->RedfishService, Private->Uri, Json, &Response);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "%a, patch resource for %s failed: %r\n", __func__, ConfigureLang, Status));
}
+ Status = GetEtagAndLocation (&Response, &EtagStr, NULL);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a, get ETag failed: %r\n", __func__, Status));
+ goto ON_RELEASE;
+ }
+
//
// Handle Etag
//
@@ -1400,6 +1421,8 @@ ProvisioningComputerSystemExistResource (
FreePool (ConfigureLang);
}
+ RedfishHttpFreeResource (&Response);
+
return Status;
}
@@ -1498,10 +1521,11 @@ RedfishUpdateResourceCommon (
IN CHAR8 *InputJson
)
{
- EFI_STATUS Status;
- CHAR8 *Json;
- EFI_STRING ConfigureLang;
- CHAR8 *EtagStr;
+ EFI_STATUS Status;
+ CHAR8 *Json;
+ EFI_STRING ConfigureLang;
+ CHAR8 *EtagStr;
+ REDFISH_RESPONSE Response;
if ((Private == NULL) || IS_EMPTY_STRING (InputJson)) {
return EFI_INVALID_PARAMETER;
@@ -1510,6 +1534,7 @@ RedfishUpdateResourceCommon (
EtagStr = NULL;
Json = NULL;
ConfigureLang = NULL;
+ ZeroMem (&Response, sizeof (REDFISH_RESPONSE));
ConfigureLang = RedfishGetConfigLanguage (Private->Uri);
if (ConfigureLang == NULL) {
@@ -1536,13 +1561,19 @@ RedfishUpdateResourceCommon (
DEBUG ((REDFISH_DEBUG_TRACE, "%a, update resource for %s\n", __func__, ConfigureLang));
//
- // PUT back to instance
+ // PATCH back to instance
//
- Status = CreatePayloadToPatchResource (Private->RedfishService, Private->Payload, Json, &EtagStr);
+ Status = RedfishHttpPatchResource (Private->RedfishService, Private->Uri, Json, &Response);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "%a, patch resource for %s failed: %r\n", __func__, ConfigureLang, Status));
}
+ Status = GetEtagAndLocation (&Response, &EtagStr, NULL);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a, get ETag failed: %r\n", __func__, Status));
+ goto ON_RELEASE;
+ }
+
//
// Handle Etag
//
@@ -1561,6 +1592,8 @@ RedfishUpdateResourceCommon (
FreePool (ConfigureLang);
}
+ RedfishHttpFreeResource (&Response);
+
return Status;
}
@@ -1621,7 +1654,7 @@ RedfishIdentifyResourceCommon (
//
// Keep URI and ConfigLang mapping
//
- RedfisSetRedfishUri (ConfigLangList.List[0].ConfigureLang, Private->Uri);
+ RedfishSetRedfishUri (ConfigLangList.List[0].ConfigureLang, Private->Uri);
//
// Set the configuration language in the RESOURCE_INFORMATION_EXCHANGE.
// This information is sent back to the parent resource (e.g. the collection driver).
diff --git a/RedfishClientPkg/Features/ComputerSystem/v1_5_0/Dxe/ComputerSystemDxe.c b/RedfishClientPkg/Features/ComputerSystem/v1_5_0/Dxe/ComputerSystemDxe.c
index 5c2a4eadf..b28082fee 100644
--- a/RedfishClientPkg/Features/ComputerSystem/v1_5_0/Dxe/ComputerSystemDxe.c
+++ b/RedfishClientPkg/Features/ComputerSystem/v1_5_0/Dxe/ComputerSystemDxe.c
@@ -50,7 +50,8 @@ RedfishResourceProvisioningResource (
return EFI_NOT_READY;
}
- Status = GetResourceByUri (Private->RedfishService, Uri, &Response);
+ ZeroMem (&Response, sizeof (Response));
+ Status = RedfishHttpGetResource (Private->RedfishService, Uri, &Response, TRUE);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "%a, get resource from: %s failed\n", __func__, Uri));
return Status;
@@ -66,12 +67,7 @@ RedfishResourceProvisioningResource (
// Release resource
//
if (Private->Payload != NULL) {
- RedfishFreeResponse (
- Response.StatusCode,
- Response.HeaderCount,
- Response.Headers,
- Response.Payload
- );
+ RedfishHttpFreeResource (&Response);
Private->Payload = NULL;
}
@@ -110,7 +106,8 @@ RedfishResourceConsumeResource (
return EFI_NOT_READY;
}
- Status = GetResourceByUri (Private->RedfishService, Uri, &Response);
+ ZeroMem (&Response, sizeof (Response));
+ Status = RedfishHttpGetResource (Private->RedfishService, Uri, &Response, TRUE);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "%a, get resource from: %s failed\n", __func__, Uri));
return Status;
@@ -150,12 +147,7 @@ RedfishResourceConsumeResource (
// Release resource
//
if (Private->Payload != NULL) {
- RedfishFreeResponse (
- Response.StatusCode,
- Response.HeaderCount,
- Response.Headers,
- Response.Payload
- );
+ RedfishHttpFreeResource (&Response);
Private->Payload = NULL;
}
@@ -234,7 +226,8 @@ RedfishResourceUpdate (
return EFI_NOT_READY;
}
- Status = GetResourceByUri (Private->RedfishService, Uri, &Response);
+ ZeroMem (&Response, sizeof (Response));
+ Status = RedfishHttpGetResource (Private->RedfishService, Uri, &Response, TRUE);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "%a, get resource from: %s failed\n", __func__, Uri));
return Status;
@@ -256,12 +249,7 @@ RedfishResourceUpdate (
// Release resource
//
if (Private->Payload != NULL) {
- RedfishFreeResponse (
- Response.StatusCode,
- Response.HeaderCount,
- Response.Headers,
- Response.Payload
- );
+ RedfishHttpFreeResource (&Response);
Private->Payload = NULL;
}
@@ -304,7 +292,8 @@ RedfishResourceCheck (
return EFI_NOT_READY;
}
- Status = GetResourceByUri (Private->RedfishService, Uri, &Response);
+ ZeroMem (&Response, sizeof (Response));
+ Status = RedfishHttpGetResource (Private->RedfishService, Uri, &Response, TRUE);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "%a, get resource from: %s failed\n", __func__, Uri));
return Status;
@@ -326,12 +315,7 @@ RedfishResourceCheck (
// Release resource
//
if (Private->Payload != NULL) {
- RedfishFreeResponse (
- Response.StatusCode,
- Response.HeaderCount,
- Response.Headers,
- Response.Payload
- );
+ RedfishHttpFreeResource (&Response);
Private->Payload = NULL;
}
@@ -375,7 +359,8 @@ RedfishResourceIdentify (
return EFI_NOT_READY;
}
- Status = GetResourceByUri (Private->RedfishService, Uri, &Response);
+ ZeroMem (&Response, sizeof (Response));
+ Status = RedfishHttpGetResource (Private->RedfishService, Uri, &Response, TRUE);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "%a, get resource from: %s failed\n", __func__, Uri));
return Status;
@@ -397,12 +382,7 @@ RedfishResourceIdentify (
// Release resource
//
if (Private->Payload != NULL) {
- RedfishFreeResponse (
- Response.StatusCode,
- Response.HeaderCount,
- Response.Headers,
- Response.Payload
- );
+ RedfishHttpFreeResource (&Response);
Private->Payload = NULL;
}
diff --git a/RedfishClientPkg/Features/ComputerSystem/v1_5_0/Dxe/ComputerSystemDxe.inf b/RedfishClientPkg/Features/ComputerSystem/v1_5_0/Dxe/ComputerSystemDxe.inf
index 67412f5f3..2c8882995 100644
--- a/RedfishClientPkg/Features/ComputerSystem/v1_5_0/Dxe/ComputerSystemDxe.inf
+++ b/RedfishClientPkg/Features/ComputerSystem/v1_5_0/Dxe/ComputerSystemDxe.inf
@@ -1,6 +1,7 @@
## @file
#
# (C) Copyright 2020-2022 Hewlett Packard Enterprise Development LP
+# Copyright (c) 2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
#
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
@@ -36,7 +37,7 @@
RedfishResourceIdentifyLib
UefiLib
UefiDriverEntryPoint
-
+ RedfishHttpLib
[Protocols]
gEdkIIRedfishConfigHandlerProtocolGuid ## PRODUCED
diff --git a/RedfishClientPkg/Features/ComputerSystemCollectionDxe/ComputerSystemCollectionDxe.c b/RedfishClientPkg/Features/ComputerSystemCollectionDxe/ComputerSystemCollectionDxe.c
index 1e362d49c..e4fe6965a 100644
--- a/RedfishClientPkg/Features/ComputerSystemCollectionDxe/ComputerSystemCollectionDxe.c
+++ b/RedfishClientPkg/Features/ComputerSystemCollectionDxe/ComputerSystemCollectionDxe.c
@@ -247,16 +247,7 @@ ReleaseCollectionResource (
// Release resource
//
if (Private->RedResponse.Payload != NULL) {
- RedfishFreeResponse (
- Private->RedResponse.StatusCode,
- Private->RedResponse.HeaderCount,
- Private->RedResponse.Headers,
- Private->RedResponse.Payload
- );
- Private->RedResponse.StatusCode = NULL;
- Private->RedResponse.HeaderCount = 0;
- Private->RedResponse.Headers = NULL;
- Private->RedResponse.Payload = NULL;
+ RedfishHttpFreeResource (&Private->RedResponse);
}
if (Private->CollectionJson != NULL) {
@@ -288,7 +279,8 @@ CollectionHandler (
//
// Query collection from Redfish service.
//
- Status = GetResourceByUri (Private->RedfishService, Private->CollectionUri, &Private->RedResponse);
+ ZeroMem (&Private->RedResponse, sizeof (Private->RedResponse));
+ Status = RedfishHttpGetResource (Private->RedfishService, Private->CollectionUri, &Private->RedResponse, TRUE);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "%a, unable to get resource from: %s :%r\n", __func__, Private->CollectionUri, Status));
goto ON_RELEASE;
diff --git a/RedfishClientPkg/Features/ComputerSystemCollectionDxe/ComputerSystemCollectionDxe.inf b/RedfishClientPkg/Features/ComputerSystemCollectionDxe/ComputerSystemCollectionDxe.inf
index 107d6c076..4d5e47ca9 100644
--- a/RedfishClientPkg/Features/ComputerSystemCollectionDxe/ComputerSystemCollectionDxe.inf
+++ b/RedfishClientPkg/Features/ComputerSystemCollectionDxe/ComputerSystemCollectionDxe.inf
@@ -3,6 +3,7 @@
# Redfish ComputerSystemCollection collection driver.
#
# (C) Copyright 2020-2022 Hewlett Packard Enterprise Development LP
+# Copyright (c) 2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
#
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
@@ -40,6 +41,7 @@
UefiBootServicesTableLib
EdkIIRedfishResourceConfigLib
RedfishVersionLib
+ RedfishHttpLib
[Protocols]
gEdkIIRedfishConfigHandlerProtocolGuid ## CONSUMED
diff --git a/RedfishClientPkg/Features/Memory/V1_7_1/Common/MemoryCommon.c b/RedfishClientPkg/Features/Memory/V1_7_1/Common/MemoryCommon.c
index b74340362..5e4aeeb21 100644
--- a/RedfishClientPkg/Features/Memory/V1_7_1/Common/MemoryCommon.c
+++ b/RedfishClientPkg/Features/Memory/V1_7_1/Common/MemoryCommon.c
@@ -2,6 +2,7 @@
Redfish feature driver implementation - common functions
(C) Copyright 2020-2022 Hewlett Packard Enterprise Development LP
+ Copyright (c) 2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -2152,17 +2153,21 @@ ProvisioningMemoryResource (
IN EFI_STRING ConfigureLang
)
{
- CHAR8 *Json;
- EFI_STATUS Status;
- EFI_STRING NewResourceLocation;
- CHAR8 *EtagStr;
- CHAR8 ResourceId[16];
+ CHAR8 *Json;
+ EFI_STATUS Status;
+ EFI_STRING NewResourceLocation;
+ CHAR8 *EtagStr;
+ CHAR8 ResourceId[16];
+ REDFISH_RESPONSE Response;
if (IS_EMPTY_STRING (ConfigureLang) || (Private == NULL)) {
return EFI_INVALID_PARAMETER;
}
- EtagStr = NULL;
+ EtagStr = NULL;
+ Json = NULL;
+ NewResourceLocation = NULL;
+ ZeroMem (&Response, sizeof (REDFISH_RESPONSE));
AsciiSPrint (ResourceId, sizeof (ResourceId), "%d", Index);
Status = ProvisioningMemoryProperties (
@@ -2178,19 +2183,25 @@ ProvisioningMemoryResource (
return Status;
}
- Status = CreatePayloadToPostResource (Private->RedfishService, Private->Payload, Json, &NewResourceLocation, &EtagStr);
+ Status = RedfishHttpPostResource (Private->RedfishService, Private->Uri, Json, &Response);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "%a, post Memory resource for %s failed: %r\n", __func__, ConfigureLang, Status));
goto RELEASE_RESOURCE;
}
+ Status = GetEtagAndLocation (&Response, &EtagStr, &NewResourceLocation);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a, get ETag and location failed: %r\n", __func__, Status));
+ goto RELEASE_RESOURCE;
+ }
+
ASSERT (NewResourceLocation != NULL);
//
// Keep location of new resource.
//
if (NewResourceLocation != NULL) {
- RedfisSetRedfishUri (ConfigureLang, NewResourceLocation);
+ RedfishSetRedfishUri (ConfigureLang, NewResourceLocation);
}
//
@@ -2211,6 +2222,8 @@ ProvisioningMemoryResource (
FreePool (Json);
}
+ RedfishHttpFreeResource (&Response);
+
return Status;
}
@@ -2253,10 +2266,11 @@ ProvisioningMemoryExistResource (
IN REDFISH_RESOURCE_COMMON_PRIVATE *Private
)
{
- EFI_STATUS Status;
- EFI_STRING ConfigureLang;
- CHAR8 *EtagStr;
- CHAR8 *Json;
+ EFI_STATUS Status;
+ EFI_STRING ConfigureLang;
+ CHAR8 *EtagStr;
+ CHAR8 *Json;
+ REDFISH_RESPONSE Response;
if (Private == NULL) {
return EFI_INVALID_PARAMETER;
@@ -2265,6 +2279,7 @@ ProvisioningMemoryExistResource (
EtagStr = NULL;
Json = NULL;
ConfigureLang = NULL;
+ ZeroMem (&Response, sizeof (REDFISH_RESPONSE));
ConfigureLang = RedfishGetConfigLanguage (Private->Uri);
if (ConfigureLang == NULL) {
@@ -2291,13 +2306,19 @@ ProvisioningMemoryExistResource (
DEBUG ((REDFISH_DEBUG_TRACE, "%a, provisioning existing resource for %s\n", __func__, ConfigureLang));
//
- // PUT back to instance
+ // PATCH back to instance
//
- Status = CreatePayloadToPatchResource (Private->RedfishService, Private->Payload, Json, &EtagStr);
+ Status = RedfishHttpPatchResource (Private->RedfishService, Private->Uri, Json, &Response);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "%a, patch resource for %s failed: %r\n", __func__, ConfigureLang, Status));
}
+ Status = GetEtagAndLocation (&Response, &EtagStr, NULL);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a, get ETag failed: %r\n", __func__, Status));
+ goto ON_RELEASE;
+ }
+
//
// Handle Etag
//
@@ -2316,6 +2337,8 @@ ProvisioningMemoryExistResource (
FreePool (ConfigureLang);
}
+ RedfishHttpFreeResource (&Response);
+
return Status;
}
@@ -2414,10 +2437,11 @@ RedfishUpdateResourceCommon (
IN CHAR8 *InputJson
)
{
- EFI_STATUS Status;
- CHAR8 *Json;
- EFI_STRING ConfigureLang;
- CHAR8 *EtagStr;
+ EFI_STATUS Status;
+ CHAR8 *Json;
+ EFI_STRING ConfigureLang;
+ CHAR8 *EtagStr;
+ REDFISH_RESPONSE Response;
if ((Private == NULL) || IS_EMPTY_STRING (InputJson)) {
return EFI_INVALID_PARAMETER;
@@ -2426,6 +2450,7 @@ RedfishUpdateResourceCommon (
EtagStr = NULL;
Json = NULL;
ConfigureLang = NULL;
+ ZeroMem (&Response, sizeof (REDFISH_RESPONSE));
ConfigureLang = RedfishGetConfigLanguage (Private->Uri);
if (ConfigureLang == NULL) {
@@ -2452,13 +2477,19 @@ RedfishUpdateResourceCommon (
DEBUG ((REDFISH_DEBUG_TRACE, "%a, update resource for %s\n", __func__, ConfigureLang));
//
- // PUT back to instance
+ // PATCH back to instance
//
- Status = CreatePayloadToPatchResource (Private->RedfishService, Private->Payload, Json, &EtagStr);
+ Status = RedfishHttpPatchResource (Private->RedfishService, Private->Uri, Json, &Response);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "%a, patch resource for %s failed: %r\n", __func__, ConfigureLang, Status));
}
+ Status = GetEtagAndLocation (&Response, &EtagStr, NULL);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a, get ETag failed: %r\n", __func__, Status));
+ goto ON_RELEASE;
+ }
+
//
// Handle Etag
//
@@ -2477,6 +2508,8 @@ RedfishUpdateResourceCommon (
FreePool (ConfigureLang);
}
+ RedfishHttpFreeResource (&Response);
+
return Status;
}
@@ -2537,7 +2570,7 @@ RedfishIdentifyResourceCommon (
//
// Keep URI and ConfigLang mapping
//
- RedfisSetRedfishUri (ConfigLangList.List[0].ConfigureLang, Private->Uri);
+ RedfishSetRedfishUri (ConfigLangList.List[0].ConfigureLang, Private->Uri);
//
// Set the configuration language in the RESOURCE_INFORMATION_EXCHANGE.
// This information is sent back to the parent resource (e.g. the collection driver).
diff --git a/RedfishClientPkg/Features/Memory/V1_7_1/Dxe/MemoryDxe.c b/RedfishClientPkg/Features/Memory/V1_7_1/Dxe/MemoryDxe.c
index f34f3266f..b09727092 100644
--- a/RedfishClientPkg/Features/Memory/V1_7_1/Dxe/MemoryDxe.c
+++ b/RedfishClientPkg/Features/Memory/V1_7_1/Dxe/MemoryDxe.c
@@ -50,7 +50,8 @@ RedfishResourceProvisioningResource (
return EFI_NOT_READY;
}
- Status = GetResourceByUri (Private->RedfishService, Uri, &Response);
+ ZeroMem (&Response, sizeof (Response));
+ Status = RedfishHttpGetResource (Private->RedfishService, Uri, &Response, TRUE);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "%a, get resource from: %s failed\n", __func__, Uri));
return Status;
@@ -66,12 +67,7 @@ RedfishResourceProvisioningResource (
// Release resource
//
if (Private->Payload != NULL) {
- RedfishFreeResponse (
- Response.StatusCode,
- Response.HeaderCount,
- Response.Headers,
- Response.Payload
- );
+ RedfishHttpFreeResource (&Response);
Private->Payload = NULL;
}
@@ -110,7 +106,8 @@ RedfishResourceConsumeResource (
return EFI_NOT_READY;
}
- Status = GetResourceByUri (Private->RedfishService, Uri, &Response);
+ ZeroMem (&Response, sizeof (Response));
+ Status = RedfishHttpGetResource (Private->RedfishService, Uri, &Response, TRUE);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "%a, get resource from: %s failed\n", __func__, Uri));
return Status;
@@ -150,12 +147,7 @@ RedfishResourceConsumeResource (
// Release resource
//
if (Private->Payload != NULL) {
- RedfishFreeResponse (
- Response.StatusCode,
- Response.HeaderCount,
- Response.Headers,
- Response.Payload
- );
+ RedfishHttpFreeResource (&Response);
Private->Payload = NULL;
}
@@ -234,7 +226,8 @@ RedfishResourceUpdate (
return EFI_NOT_READY;
}
- Status = GetResourceByUri (Private->RedfishService, Uri, &Response);
+ ZeroMem (&Response, sizeof (Response));
+ Status = RedfishHttpGetResource (Private->RedfishService, Uri, &Response, TRUE);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "%a, get resource from: %s failed\n", __func__, Uri));
return Status;
@@ -256,12 +249,7 @@ RedfishResourceUpdate (
// Release resource
//
if (Private->Payload != NULL) {
- RedfishFreeResponse (
- Response.StatusCode,
- Response.HeaderCount,
- Response.Headers,
- Response.Payload
- );
+ RedfishHttpFreeResource (&Response);
Private->Payload = NULL;
}
@@ -304,7 +292,8 @@ RedfishResourceCheck (
return EFI_NOT_READY;
}
- Status = GetResourceByUri (Private->RedfishService, Uri, &Response);
+ ZeroMem (&Response, sizeof (Response));
+ Status = RedfishHttpGetResource (Private->RedfishService, Uri, &Response, TRUE);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "%a, get resource from: %s failed\n", __func__, Uri));
return Status;
@@ -326,12 +315,7 @@ RedfishResourceCheck (
// Release resource
//
if (Private->Payload != NULL) {
- RedfishFreeResponse (
- Response.StatusCode,
- Response.HeaderCount,
- Response.Headers,
- Response.Payload
- );
+ RedfishHttpFreeResource (&Response);
Private->Payload = NULL;
}
@@ -375,7 +359,8 @@ RedfishResourceIdentify (
return EFI_NOT_READY;
}
- Status = GetResourceByUri (Private->RedfishService, Uri, &Response);
+ ZeroMem (&Response, sizeof (Response));
+ Status = RedfishHttpGetResource (Private->RedfishService, Uri, &Response, TRUE);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "%a, get resource from: %s failed\n", __func__, Uri));
return Status;
@@ -397,12 +382,7 @@ RedfishResourceIdentify (
// Release resource
//
if (Private->Payload != NULL) {
- RedfishFreeResponse (
- Response.StatusCode,
- Response.HeaderCount,
- Response.Headers,
- Response.Payload
- );
+ RedfishHttpFreeResource (&Response);
Private->Payload = NULL;
}
diff --git a/RedfishClientPkg/Features/Memory/V1_7_1/Dxe/MemoryDxe.inf b/RedfishClientPkg/Features/Memory/V1_7_1/Dxe/MemoryDxe.inf
index 594a87490..ab862f694 100644
--- a/RedfishClientPkg/Features/Memory/V1_7_1/Dxe/MemoryDxe.inf
+++ b/RedfishClientPkg/Features/Memory/V1_7_1/Dxe/MemoryDxe.inf
@@ -1,6 +1,7 @@
## @file
#
# (C) Copyright 2020-2022 Hewlett Packard Enterprise Development LP
+# Copyright (c) 2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
#
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
@@ -36,7 +37,7 @@
RedfishResourceIdentifyLib
UefiLib
UefiDriverEntryPoint
-
+ RedfishHttpLib
[Protocols]
gEdkIIRedfishConfigHandlerProtocolGuid ## PRODUCED
diff --git a/RedfishClientPkg/Features/MemoryCollectionDxe/MemoryCollectionDxe.c b/RedfishClientPkg/Features/MemoryCollectionDxe/MemoryCollectionDxe.c
index 1b755cde0..dce555af6 100644
--- a/RedfishClientPkg/Features/MemoryCollectionDxe/MemoryCollectionDxe.c
+++ b/RedfishClientPkg/Features/MemoryCollectionDxe/MemoryCollectionDxe.c
@@ -247,16 +247,7 @@ ReleaseCollectionResource (
// Release resource
//
if (Private->RedResponse.Payload != NULL) {
- RedfishFreeResponse (
- Private->RedResponse.StatusCode,
- Private->RedResponse.HeaderCount,
- Private->RedResponse.Headers,
- Private->RedResponse.Payload
- );
- Private->RedResponse.StatusCode = NULL;
- Private->RedResponse.HeaderCount = 0;
- Private->RedResponse.Headers = NULL;
- Private->RedResponse.Payload = NULL;
+ RedfishHttpFreeResource (&Private->RedResponse);
}
if (Private->CollectionJson != NULL) {
@@ -288,7 +279,8 @@ CollectionHandler (
//
// Query collection from Redfish service.
//
- Status = GetResourceByUri (Private->RedfishService, Private->CollectionUri, &Private->RedResponse);
+ ZeroMem (&Private->RedResponse, sizeof (Private->RedResponse));
+ Status = RedfishHttpGetResource (Private->RedfishService, Private->CollectionUri, &Private->RedResponse, TRUE);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "%a, unable to get resource from: %s :%r\n", __func__, Private->CollectionUri, Status));
goto ON_RELEASE;
diff --git a/RedfishClientPkg/Features/MemoryCollectionDxe/MemoryCollectionDxe.inf b/RedfishClientPkg/Features/MemoryCollectionDxe/MemoryCollectionDxe.inf
index 05e05712e..099116783 100644
--- a/RedfishClientPkg/Features/MemoryCollectionDxe/MemoryCollectionDxe.inf
+++ b/RedfishClientPkg/Features/MemoryCollectionDxe/MemoryCollectionDxe.inf
@@ -3,6 +3,7 @@
# Redfish MemoryCollection collection driver.
#
# (C) Copyright 2020-2022 Hewlett Packard Enterprise Development LP
+# Copyright (c) 2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
#
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
@@ -40,6 +41,7 @@
UefiBootServicesTableLib
EdkIIRedfishResourceConfigLib
RedfishVersionLib
+ RedfishHttpLib
[Protocols]
gEdkIIRedfishConfigHandlerProtocolGuid ## CONSUMED
diff --git a/RedfishClientPkg/Include/Library/RedfishFeatureUtilityLib.h b/RedfishClientPkg/Include/Library/RedfishFeatureUtilityLib.h
index e2f728b26..4906a55ab 100644
--- a/RedfishClientPkg/Include/Library/RedfishFeatureUtilityLib.h
+++ b/RedfishClientPkg/Include/Library/RedfishFeatureUtilityLib.h
@@ -11,32 +11,13 @@
#ifndef REDFISH_FEATURE_UTILITY_LIB_H_
#define REDFISH_FEATURE_UTILITY_LIB_H_
-#include
#include
#include
#include
+#include
#define REDFISH_ENABLE_SYSTEM_REBOOT() PcdSetBoolS(PcdRedfishSystemRebootRequired, TRUE)
-/**
-
- Read redfish resource by given resource URI.
-
- @param[in] Service Redfish srvice instacne to make query.
- @param[in] ResourceUri Target resource URI.
- @param[out] Response HTTP response from redfish service.
-
- @retval EFI_SUCCESS Resrouce is returned successfully.
- @retval Others Errors occur.
-
-**/
-EFI_STATUS
-GetResourceByUri (
- IN REDFISH_SERVICE *Service,
- IN EFI_STRING ResourceUri,
- OUT REDFISH_RESPONSE *Response
- );
-
/**
Check if this is the Redpath array. Usually the Redpath array represents
@@ -47,7 +28,7 @@ GetResourceByUri (
@param[out] ArraySignatureClose String to the close of array signature.
@retval EFI_SUCCESS Index is found.
- @retval EFI_NOT_FOUND The non-array configure language string is retured.
+ @retval EFI_NOT_FOUND The non-array configure language string is returned.
@retval EFI_INVALID_PARAMETER The format of input ConfigureLang is wrong.
@retval Others Errors occur.
@@ -100,7 +81,7 @@ CopyConfiglanguageList (
/**
- Get number of node from the string. Node is seperated by '/'.
+ Get number of node from the string. Node is separated by '/'.
@param[in] NodeString The node string to parse.
@@ -118,10 +99,10 @@ GetNumberOfRedpathNodes (
@param[in] NodeString The node string to parse.
@param[in] Index Index of the node.
- @param[out] EndOfNodePtr Pointer to receive the poitner to
+ @param[out] EndOfNodePtr Pointer to receive the pointer to
the last character of node string.
- @retval EFI_STRING the begining of the node string.
+ @retval EFI_STRING the beginning of the node string.
**/
EFI_STRING
@@ -140,7 +121,7 @@ GetRedpathNodeByIndex (
@param[out] Index The array index number.
@retval EFI_SUCCESS Index is found.
- @retval EFI_NOT_FOUND The non-array configure language string is retured.
+ @retval EFI_NOT_FOUND The non-array configure language string is returned.
@retval EFI_INVALID_PARAMETER The format of input ConfigureLang is wrong.
@retval Others Errors occur.
@@ -188,7 +169,7 @@ DestroyConfiglanguageList (
@param[in] DestConfigLang Pointer to the node's configure language string.
The memory pointed by ConfigLang must be allocated
- through memory allocation interface. Becasue we will replace
+ through memory allocation interface. Because we will replace
the pointer in this function.
@param[in] MaxtLengthConfigLang The maximum length of ConfigLang.
@param[in] ConfigLangInstance Pointer to Collection member instance.
@@ -244,7 +225,7 @@ ApplyFeatureSettingsStringType (
/**
- Apply property value to UEFI HII database in numric type.
+ Apply property value to UEFI HII database in numeric type.
@param[in] Schema Property schema.
@param[in] Version Property schema version.
@@ -356,7 +337,7 @@ ApplyFeatureSettingsNumericArrayType (
@param[in] Schema Property schema.
@param[in] Version Property schema version.
@param[in] ConfigureLang Configure language refers to this property.
- @param[in] ArrayHead Head of Redfich CS boolean array value.
+ @param[in] ArrayHead Head of Redfish CS boolean array value.
@retval EFI_SUCCESS New value is applied successfully.
@retval Others Errors occur.
@@ -370,50 +351,6 @@ ApplyFeatureSettingsBooleanArrayType (
IN RedfishCS_bool_Array *ArrayHead
);
-/**
-
- Create HTTP payload and send them to redfish service with POST method.
-
- @param[in] Service Redfish service.
- @param[in] TargetPayload Target payload
- @param[in] Json Data in JSON format.
- @param[out] Location Returned location string from Redfish service.
- @param[out] Etag Returned ETAG string from Redfish service.
-
- @retval EFI_SUCCESS Data is sent to redfish service successfully.
- @retval Others Errors occur.
-
-**/
-EFI_STATUS
-CreatePayloadToPostResource (
- IN REDFISH_SERVICE *Service,
- IN REDFISH_PAYLOAD *TargetPayload,
- IN CHAR8 *Json,
- OUT EFI_STRING *Location,
- OUT CHAR8 **Etag
- );
-
-/**
-
- Create HTTP payload and send them to redfish service with PATCH method.
-
- @param[in] Service Redfish service.
- @param[in] TargetPayload Target payload
- @param[in] Json Data in JSON format.
- @param[out] Etag Returned ETAG string from Redfish service.
-
- @retval EFI_SUCCESS Data is sent to redfish service successfully.
- @retval Others Errors occur.
-
-**/
-EFI_STATUS
-CreatePayloadToPatchResource (
- IN REDFISH_SERVICE *Service,
- IN REDFISH_PAYLOAD *TargetPayload,
- IN CHAR8 *Json,
- OUT CHAR8 **Etag
- );
-
/**
Save Redfish URI in database for further use.
@@ -421,19 +358,19 @@ CreatePayloadToPatchResource (
@param[in] ConfigLang ConfigLang to save
@param[in] Uri Redfish Uri to save
- @retval EFI_INVALID_PARAMETR SystemId is NULL or EMPTY
+ @retval EFI_INVALID_PARAMETER SystemId is NULL or EMPTY
@retval EFI_SUCCESS Redfish uri is saved
**/
EFI_STATUS
-RedfisSetRedfishUri (
+RedfishSetRedfishUri (
IN EFI_STRING ConfigLang,
IN EFI_STRING Uri
);
/**
- Get the property name by given Configure Langauge.
+ Get the property name by given Configure Language.
@param[in] ResourceUri URI of root of resource.
@param[in] ConfigureLang Configure Language string.
@@ -576,7 +513,7 @@ GetOdataId (
/**
- Return config language from given URI and prperty name. It's call responsibility to release returned buffer.
+ Return config language from given URI and property name. It's call responsibility to release returned buffer.
@param[in] Uri The URI to match
@param[in] PropertyName The property name of resource. This is optional.
@@ -790,7 +727,7 @@ MatchPropertyWithJsonContext (
/**
- Create string array and append to arry node in Redfish JSON convert format.
+ Create string array and append to array node in Redfish JSON convert format.
@param[in,out] Head The head of string array.
@param[in] StringArray Input string array.
@@ -809,7 +746,7 @@ AddRedfishCharArray (
/**
- Create numeric array and append to arry node in Redfish JSON convert format.
+ Create numeric array and append to array node in Redfish JSON convert format.
@param[in,out] Head The head of string array.
@param[in] NumericArray Input numeric array.
@@ -828,7 +765,7 @@ AddRedfishNumericArray (
/**
- Create boolean array and append to arry node in Redfish JSON convert format.
+ Create boolean array and append to array node in Redfish JSON convert format.
@param[in,out] Head The head of string array.
@param[in] BooleanArray Input boolean array.
@@ -871,7 +808,7 @@ CompareRedfishStringArrayValues (
Check and see if value in Redfish numeric array are all the same as the one
from HII configuration.
- @param[in] Head The head of Redfish CS numeraic array.
+ @param[in] Head The head of Redfish CS numeric array.
@param[in] NumericArray Input numeric array.
@param[in] ArraySize The size of NumericArray.
@@ -914,9 +851,9 @@ CompareRedfishBooleanArrayValues (
This is just a simple check.
@param[in] RedfishVagueKeyValuePtr The vague key value sets on Redfish service.
- @param[in] RedfishVagueKeyValueNumber The numebr of vague key value sets
+ @param[in] RedfishVagueKeyValueNumber The number of vague key value sets
@param[in] ConfigVagueKeyValuePtr The vague configuration on platform.
- @param[in] ConfigVagueKeyValueNumber The numebr of vague key value sets
+ @param[in] ConfigVagueKeyValueNumber The number of vague key value sets
@retval TRUE All values are the same.
FALSE There is some difference.
diff --git a/RedfishClientPkg/Include/Library/RedfishHttpLib.h b/RedfishClientPkg/Include/Library/RedfishHttpLib.h
new file mode 100644
index 000000000..ab7cf0a80
--- /dev/null
+++ b/RedfishClientPkg/Include/Library/RedfishHttpLib.h
@@ -0,0 +1,150 @@
+/** @file
+ This file defines the Redfish HTTP library interface.
+
+ Copyright (c) 2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef REDFISH_HTTP_LIB_H_
+#define REDFISH_HTTP_LIB_H_
+
+#include
+
+/**
+ This function free resources in Response. Response is no longer available
+ after this function returns successfully.
+
+ @param[in] Response HTTP response to be released.
+
+ @retval EFI_SUCCESS Resrouce is released successfully.
+ @retval Others Errors occur.
+
+**/
+EFI_STATUS
+RedfishHttpFreeResource (
+ IN REDFISH_RESPONSE *Response
+ );
+
+/**
+ Get redfish resource from given resource URI with cache mechanism
+ supported. It's caller's responsibility to Response by calling
+ RedfishHttpFreeResource ().
+
+ @param[in] Service Redfish service instance to make query.
+ @param[in] Uri Target resource URI.
+ @param[out] Response HTTP response from redfish service.
+ @param[in] UseCache If it is TRUE, this function will search for
+ cache first. If it is FALSE, this function
+ will query Redfish URI directly.
+
+ @retval EFI_SUCCESS Resrouce is returned successfully.
+ @retval Others Errors occur.
+
+**/
+EFI_STATUS
+RedfishHttpGetResource (
+ IN REDFISH_SERVICE Service,
+ IN EFI_STRING Uri,
+ OUT REDFISH_RESPONSE *Response,
+ IN BOOLEAN UseCache
+ );
+
+/**
+ This function expire the cached response of given URI.
+
+ @param[in] Uri Target response of URI.
+
+ @retval EFI_SUCCESS Target response is expired successfully.
+ @retval Others Errors occur.
+
+**/
+EFI_STATUS
+RedfishHttpExpireResponse (
+ IN EFI_STRING Uri
+ );
+
+/**
+ Perform HTTP PATCH to send redfish resource to given resource URI.
+ It's caller's responsibility to free Response by calling FreeResponse ().
+
+ @param[in] Service Redfish service instance to make query.
+ @param[in] Uri Target resource URI.
+ @param[in] Content Data to patch.
+ @param[out] Response HTTP response from redfish service.
+
+ @retval EFI_SUCCESS Resrouce is returned successfully.
+ @retval Others Errors occur.
+
+**/
+EFI_STATUS
+RedfishHttpPatchResource (
+ IN REDFISH_SERVICE Service,
+ IN EFI_STRING Uri,
+ IN CHAR8 *Content,
+ OUT REDFISH_RESPONSE *Response
+ );
+
+/**
+ Perform HTTP PUT to send redfish resource to given resource URI.
+ It's caller's responsibility to free Response by calling FreeResponse ().
+
+ @param[in] Service Redfish service instance to make query.
+ @param[in] Uri Target resource URI.
+ @param[in] Content Data to put.
+ @param[out] Response HTTP response from redfish service.
+
+ @retval EFI_SUCCESS Resrouce is returned successfully.
+ @retval Others Errors occur.
+
+**/
+EFI_STATUS
+RedfishHttpPutResource (
+ IN REDFISH_SERVICE Service,
+ IN EFI_STRING Uri,
+ IN CHAR8 *Content,
+ OUT REDFISH_RESPONSE *Response
+ );
+
+/**
+ Perform HTTP POST to send redfish resource to given resource URI.
+ It's caller's responsibility to free Response by calling FreeResponse ().
+
+ @param[in] Service Redfish service instance to make query.
+ @param[in] Uri Target resource URI.
+ @param[in] Content Data to post.
+ @param[out] Response HTTP response from redfish service.
+
+ @retval EFI_SUCCESS Resrouce is returned successfully.
+ @retval Others Errors occur.
+
+**/
+EFI_STATUS
+RedfishHttpPostResource (
+ IN REDFISH_SERVICE Service,
+ IN EFI_STRING Uri,
+ IN CHAR8 *Content,
+ OUT REDFISH_RESPONSE *Response
+ );
+
+/**
+ Perform HTTP DELETE to delete redfish resource on given resource URI.
+ It's caller's responsibility to free Response by calling FreeResponse ().
+
+ @param[in] Service Redfish service instance to make query.
+ @param[in] Uri Target resource URI.
+ @param[out] Response HTTP response from redfish service.
+
+ @retval EFI_SUCCESS Resrouce is returned successfully.
+ @retval Others Errors occur.
+
+**/
+EFI_STATUS
+RedfishHttpDeleteResource (
+ IN REDFISH_SERVICE Service,
+ IN EFI_STRING Uri,
+ OUT REDFISH_RESPONSE *Response
+ );
+
+#endif
diff --git a/RedfishClientPkg/Include/Library/RedfishVersionLib.h b/RedfishClientPkg/Include/Library/RedfishVersionLib.h
index 319f22bd3..020d14d6f 100644
--- a/RedfishClientPkg/Include/Library/RedfishVersionLib.h
+++ b/RedfishClientPkg/Include/Library/RedfishVersionLib.h
@@ -2,6 +2,7 @@
This file defines the Redfish version Library interface.
(C) Copyright 2022 Hewlett Packard Enterprise Development LP
+ Copyright (c) 2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -10,9 +11,11 @@
#ifndef REDFISH_VERSION_LIB_H_
#define REDFISH_VERSION_LIB_H_
+#include
+
/**
Query HTTP request to BMC with given redfish service and return redfish
- version information. If there is troulbe to get Redfish version on BMC,
+ version information. If there is trouble to get Redfish version on BMC,
The value of PcdDefaultRedfishVersion is returned.
It's call responsibility to release returned buffer.
diff --git a/RedfishClientPkg/Include/Protocol/EdkIIRedfishHttpProtocol.h b/RedfishClientPkg/Include/Protocol/EdkIIRedfishHttpProtocol.h
new file mode 100644
index 000000000..910c115dc
--- /dev/null
+++ b/RedfishClientPkg/Include/Protocol/EdkIIRedfishHttpProtocol.h
@@ -0,0 +1,192 @@
+/** @file
+ This file defines the EDKII_REDFISH_HTTP_PROTOCOL interface.
+
+ Copyright (c) 2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef EDKII_REDFISH_HTTP_PROTOCOL_H_
+#define EDKII_REDFISH_HTTP_PROTOCOL_H_
+
+#include
+#include
+
+typedef struct _EDKII_REDFISH_HTTP_PROTOCOL EDKII_REDFISH_HTTP_PROTOCOL;
+
+/**
+ Perform HTTP GET to Get redfish resource from given resource URI with
+ cache mechanism supported. It's caller's responsibility to free Response
+ by calling FreeResponse ().
+
+ @param[in] This Pointer to EDKII_REDFISH_HTTP_PROTOCOL instance.
+ @param[in] Service Redfish service instance to make query.
+ @param[in] Uri Target resource URI.
+ @param[out] Response HTTP response from redfish service.
+ @param[in] UseCache If it is TRUE, this function will search for
+ cache first. If it is FALSE, this function
+ will query Redfish URI directly.
+
+ @retval EFI_SUCCESS Resrouce is returned successfully.
+ @retval Others Errors occur.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *REDFISH_HTTP_GET_RESOURCE)(
+ IN EDKII_REDFISH_HTTP_PROTOCOL *This,
+ IN REDFISH_SERVICE Service,
+ IN EFI_STRING Uri,
+ OUT REDFISH_RESPONSE *Response,
+ IN BOOLEAN UseCache
+ );
+
+/**
+ This function free resources in Response. Response is no longer available
+ after this function returns successfully.
+
+ @param[in] This Pointer to EDKII_REDFISH_HTTP_PROTOCOL instance.
+ @param[in] Response HTTP response to be released.
+
+ @retval EFI_SUCCESS Resrouce is released successfully.
+ @retval Others Errors occur.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *REDFISH_HTTP_FREE_RESPONSE)(
+ IN EDKII_REDFISH_HTTP_PROTOCOL *This,
+ IN REDFISH_RESPONSE *Response
+ );
+
+/**
+ This function expire the cached response of given URI.
+
+ @param[in] This Pointer to EDKII_REDFISH_HTTP_PROTOCOL instance.
+ @param[in] Uri Target response of URI.
+
+ @retval EFI_SUCCESS Target response is expired successfully.
+ @retval Others Errors occur.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *REDFISH_HTTP_EXPIRE_RESPONSE)(
+ IN EDKII_REDFISH_HTTP_PROTOCOL *This,
+ IN EFI_STRING Uri
+ );
+
+/**
+ Perform HTTP PATCH to send redfish resource to given resource URI.
+ It's caller's responsibility to free Response by calling FreeResponse ().
+
+ @param[in] This Pointer to EDKII_REDFISH_HTTP_PROTOCOL instance.
+ @param[in] Service Redfish service instance to make query.
+ @param[in] Uri Target resource URI.
+ @param[in] Content Data to patch.
+ @param[out] Response HTTP response from redfish service.
+
+ @retval EFI_SUCCESS Resrouce is returned successfully.
+ @retval Others Errors occur.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *REDFISH_HTTP_PATCH_RESOURCE)(
+ IN EDKII_REDFISH_HTTP_PROTOCOL *This,
+ IN REDFISH_SERVICE Service,
+ IN EFI_STRING Uri,
+ IN CHAR8 *Content,
+ OUT REDFISH_RESPONSE *Response
+ );
+
+/**
+ Perform HTTP PUT to send redfish resource to given resource URI.
+ It's caller's responsibility to free Response by calling FreeResponse ().
+
+ @param[in] This Pointer to EDKII_REDFISH_HTTP_PROTOCOL instance.
+ @param[in] Service Redfish service instance to make query.
+ @param[in] Uri Target resource URI.
+ @param[in] Content Data to put.
+ @param[out] Response HTTP response from redfish service.
+
+ @retval EFI_SUCCESS Resrouce is returned successfully.
+ @retval Others Errors occur.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *REDFISH_HTTP_PUT_RESOURCE)(
+ IN EDKII_REDFISH_HTTP_PROTOCOL *This,
+ IN REDFISH_SERVICE Service,
+ IN EFI_STRING Uri,
+ IN CHAR8 *Content,
+ OUT REDFISH_RESPONSE *Response
+ );
+
+/**
+ Perform HTTP POST to send redfish resource to given resource URI.
+ It's caller's responsibility to free Response by calling FreeResponse ().
+
+ @param[in] This Pointer to EDKII_REDFISH_HTTP_PROTOCOL instance.
+ @param[in] Service Redfish service instance to make query.
+ @param[in] Uri Target resource URI.
+ @param[in] Content Data to post.
+ @param[out] Response HTTP response from redfish service.
+
+ @retval EFI_SUCCESS Resrouce is returned successfully.
+ @retval Others Errors occur.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *REDFISH_HTTP_POST_RESOURCE)(
+ IN EDKII_REDFISH_HTTP_PROTOCOL *This,
+ IN REDFISH_SERVICE Service,
+ IN EFI_STRING Uri,
+ IN CHAR8 *Content,
+ OUT REDFISH_RESPONSE *Response
+ );
+
+/**
+ Perform HTTP DELETE to delete redfish resource on given resource URI.
+ It's caller's responsibility to free Response by calling FreeResponse ().
+
+ @param[in] This Pointer to EDKII_REDFISH_HTTP_PROTOCOL instance.
+ @param[in] Service Redfish service instance to make query.
+ @param[in] Uri Target resource URI.
+ @param[out] Response HTTP response from redfish service.
+
+ @retval EFI_SUCCESS Resrouce is returned successfully.
+ @retval Others Errors occur.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *REDFISH_HTTP_DELETE_RESOURCE)(
+ IN EDKII_REDFISH_HTTP_PROTOCOL *This,
+ IN REDFISH_SERVICE Service,
+ IN EFI_STRING Uri,
+ OUT REDFISH_RESPONSE *Response
+ );
+
+///
+/// Definition of _EDKII_REDFISH_HTTP_PROTOCOL.
+///
+struct _EDKII_REDFISH_HTTP_PROTOCOL {
+ UINT32 Version;
+ REDFISH_HTTP_GET_RESOURCE GetResource;
+ REDFISH_HTTP_PATCH_RESOURCE PatchResource;
+ REDFISH_HTTP_PUT_RESOURCE PutResource;
+ REDFISH_HTTP_POST_RESOURCE PostResource;
+ REDFISH_HTTP_DELETE_RESOURCE DeleteResource;
+ REDFISH_HTTP_FREE_RESPONSE FreeResponse;
+ REDFISH_HTTP_EXPIRE_RESPONSE ExpireResponse;
+};
+
+#define EDKII_REDFISH_HTTP_PROTOCOL_REVISION 0x00001000
+
+extern EFI_GUID gEdkIIRedfishHttpProtocolGuid;
+
+#endif
diff --git a/RedfishClientPkg/Include/RedfishCollectionCommon.h b/RedfishClientPkg/Include/RedfishCollectionCommon.h
index 59cc3607f..f7730aef0 100644
--- a/RedfishClientPkg/Include/RedfishCollectionCommon.h
+++ b/RedfishClientPkg/Include/RedfishCollectionCommon.h
@@ -2,6 +2,7 @@
Redfish feature driver collection common header file.
(C) Copyright 2020-2022 Hewlett Packard Enterprise Development LP
+ Copyright (c) 2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -26,6 +27,7 @@
#include
#include
#include
+#include
//
// Protocols
diff --git a/RedfishClientPkg/Include/RedfishResourceCommon.h b/RedfishClientPkg/Include/RedfishResourceCommon.h
index b006755d6..6c20aa072 100644
--- a/RedfishClientPkg/Include/RedfishResourceCommon.h
+++ b/RedfishClientPkg/Include/RedfishResourceCommon.h
@@ -32,6 +32,7 @@
#include
#include
#include
+#include
//
// Protocols
diff --git a/RedfishClientPkg/Library/EdkIIRedfishResourceConfigLib/EdkIIRedfishResourceConfigLib.c b/RedfishClientPkg/Library/EdkIIRedfishResourceConfigLib/EdkIIRedfishResourceConfigLib.c
index ce86ce701..d2560e925 100644
--- a/RedfishClientPkg/Library/EdkIIRedfishResourceConfigLib/EdkIIRedfishResourceConfigLib.c
+++ b/RedfishClientPkg/Library/EdkIIRedfishResourceConfigLib/EdkIIRedfishResourceConfigLib.c
@@ -16,6 +16,7 @@
#include
#include
#include
+#include
EDKII_REDFISH_RESOURCE_CONFIG_PROTOCOL *mRedfishResourceConfigProtocol = NULL;
EFI_HANDLE mCachedHandle;
@@ -56,7 +57,8 @@ GetRedfishSchemaInfo (
return EFI_INVALID_PARAMETER;
}
- Status = GetResourceByUri (RedfishService, Uri, &Response);
+ ZeroMem (&Response, sizeof (Response));
+ Status = RedfishHttpGetResource (RedfishService, Uri, &Response, TRUE);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "%a, failed to get resource from %s: %r", __func__, Uri, Status));
return Status;
@@ -90,6 +92,10 @@ GetRedfishSchemaInfo (
//
// Release resource.
//
+ if (Response.Payload != NULL) {
+ RedfishHttpFreeResource (&Response);
+ }
+
JsonStructProtocol->DestoryStructure (JsonStructProtocol, Header);
FreePool (JsonText);
RedfishFreeResponse (Response.StatusCode, Response.HeaderCount, Response.Headers, Response.Payload);
diff --git a/RedfishClientPkg/Library/EdkIIRedfishResourceConfigLib/EdkIIRedfishResourceConfigLib.inf b/RedfishClientPkg/Library/EdkIIRedfishResourceConfigLib/EdkIIRedfishResourceConfigLib.inf
index 0da3423d2..f526dc619 100644
--- a/RedfishClientPkg/Library/EdkIIRedfishResourceConfigLib/EdkIIRedfishResourceConfigLib.inf
+++ b/RedfishClientPkg/Library/EdkIIRedfishResourceConfigLib/EdkIIRedfishResourceConfigLib.inf
@@ -38,6 +38,7 @@
MemoryAllocationLib
RedfishFeatureUtilityLib
RedfishPlatformConfigLib
+ RedfishHttpLib
[Protocols]
gEdkIIRedfishResourceConfigProtocolGuid ## CONSUMES ##
diff --git a/RedfishClientPkg/Library/RedfishFeatureUtilityLib/RedfishFeatureUtilityLib.c b/RedfishClientPkg/Library/RedfishFeatureUtilityLib/RedfishFeatureUtilityLib.c
index 13e29902d..d6ebc7fdf 100644
--- a/RedfishClientPkg/Library/RedfishFeatureUtilityLib/RedfishFeatureUtilityLib.c
+++ b/RedfishClientPkg/Library/RedfishFeatureUtilityLib/RedfishFeatureUtilityLib.c
@@ -1040,66 +1040,6 @@ ApplyFeatureSettingsBooleanArrayType (
return Status;
}
-/**
-
- Read redfish resource by given resource URI.
-
- @param[in] Service Redfish service instance to make query.
- @param[in] ResourceUri Target resource URI.
- @param[out] Response HTTP response from redfish service.
-
- @retval EFI_SUCCESS Resrouce is returned successfully.
- @retval Others Errors occur.
-
-**/
-EFI_STATUS
-GetResourceByUri (
- IN REDFISH_SERVICE *Service,
- IN EFI_STRING ResourceUri,
- OUT REDFISH_RESPONSE *Response
- )
-{
- EFI_STATUS Status;
- CHAR8 *AsciiResourceUri;
-
- if ((Service == NULL) || (Response == NULL) || IS_EMPTY_STRING (ResourceUri)) {
- return EFI_INVALID_PARAMETER;
- }
-
- AsciiResourceUri = StrUnicodeToAscii (ResourceUri);
- if (AsciiResourceUri == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
-
- //
- // Get resource from redfish service.
- //
- Status = RedfishGetByUri (
- Service,
- AsciiResourceUri,
- Response
- );
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "%a: RedfishGetByUri to %a failed: %r\n", __func__, AsciiResourceUri, Status));
- if (Response->Payload != NULL) {
- RedfishDumpPayload (Response->Payload);
- RedfishFreeResponse (
- NULL,
- 0,
- NULL,
- Response->Payload
- );
- Response->Payload = NULL;
- }
- }
-
- if (AsciiResourceUri != NULL) {
- FreePool (AsciiResourceUri);
- }
-
- return Status;
-}
-
/**
Check if this is the Redpath array. Usually the Redpath array represents
@@ -1773,161 +1713,6 @@ GetEtagAndLocation (
return Status;
}
-/**
-
- Create HTTP payload and send them to redfish service with PATCH method.
-
- @param[in] Service Redfish service.
- @param[in] TargetPayload Target payload
- @param[in] Json Data in JSON format.
- @param[out] Etag Returned ETAG string from Redfish service.
-
- @retval EFI_SUCCESS Data is sent to redfish service successfully.
- @retval Others Errors occur.
-
-**/
-EFI_STATUS
-CreatePayloadToPatchResource (
- IN REDFISH_SERVICE *Service,
- IN REDFISH_PAYLOAD *TargetPayload,
- IN CHAR8 *Json,
- OUT CHAR8 **Etag
- )
-{
- REDFISH_PAYLOAD Payload;
- EDKII_JSON_VALUE ResourceJsonValue;
- REDFISH_RESPONSE PostResponse;
- EFI_STATUS Status;
-
- if ((Service == NULL) || (TargetPayload == NULL) || IS_EMPTY_STRING (Json) || (Etag == NULL)) {
- return EFI_INVALID_PARAMETER;
- }
-
- ResourceJsonValue = JsonLoadString (Json, 0, NULL);
- Payload = RedfishCreatePayload (ResourceJsonValue, Service);
- if (Payload == NULL) {
- DEBUG ((DEBUG_ERROR, "%a:%d Failed to create JSON payload from JSON value!\n", __func__, __LINE__));
- Status = EFI_DEVICE_ERROR;
- goto EXIT_FREE_JSON_VALUE;
- }
-
- ZeroMem (&PostResponse, sizeof (REDFISH_RESPONSE));
- Status = RedfishPatchToPayload (TargetPayload, Payload, &PostResponse);
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "%a:%d Failed to PATCH payload to Redfish service.\n", __func__, __LINE__));
-
- DEBUG_CODE_BEGIN ();
- DEBUG ((DEBUG_ERROR, "%a: Request:\n", __func__));
- DumpRedfishPayload (DEBUG_ERROR, Payload);
- DEBUG ((DEBUG_ERROR, "%a: Response:\n", __func__));
- DumpRedfishResponse (__func__, DEBUG_ERROR, &PostResponse);
- DEBUG_CODE_END ();
- goto EXIT_FREE_JSON_VALUE;
- }
-
- //
- // Find ETag
- //
- Status = GetEtagAndLocation (&PostResponse, Etag, NULL);
- if (EFI_ERROR (Status)) {
- Status = EFI_DEVICE_ERROR;
- }
-
- RedfishFreeResponse (
- PostResponse.StatusCode,
- PostResponse.HeaderCount,
- PostResponse.Headers,
- PostResponse.Payload
- );
-
-EXIT_FREE_JSON_VALUE:
- if (Payload != NULL) {
- RedfishCleanupPayload (Payload);
- }
-
- JsonValueFree (ResourceJsonValue);
-
- return Status;
-}
-
-/**
-
- Create HTTP payload and send them to redfish service with POST method.
-
- @param[in] Service Redfish service.
- @param[in] TargetPayload Target payload
- @param[in] Json Data in JSON format.
- @param[out] Location Returned location string from Redfish service.
- @param[out] Etag Returned ETAG string from Redfish service.
-
- @retval EFI_SUCCESS Data is sent to redfish service successfully.
- @retval Others Errors occur.
-
-**/
-EFI_STATUS
-CreatePayloadToPostResource (
- IN REDFISH_SERVICE *Service,
- IN REDFISH_PAYLOAD *TargetPayload,
- IN CHAR8 *Json,
- OUT EFI_STRING *Location,
- OUT CHAR8 **Etag
- )
-{
- REDFISH_PAYLOAD Payload;
- EDKII_JSON_VALUE ResourceJsonValue;
- REDFISH_RESPONSE PostResponse;
- EFI_STATUS Status;
-
- if ((Service == NULL) || (TargetPayload == NULL) || IS_EMPTY_STRING (Json) || (Location == NULL) || (Etag == NULL)) {
- return EFI_INVALID_PARAMETER;
- }
-
- ResourceJsonValue = JsonLoadString (Json, 0, NULL);
- Payload = RedfishCreatePayload (ResourceJsonValue, Service);
- if (Payload == NULL) {
- DEBUG ((DEBUG_ERROR, "%a:%d Failed to create JSON payload from JSON value!\n", __func__, __LINE__));
- Status = EFI_DEVICE_ERROR;
- goto EXIT_FREE_JSON_VALUE;
- }
-
- ZeroMem (&PostResponse, sizeof (REDFISH_RESPONSE));
- Status = RedfishPostToPayload (TargetPayload, Payload, &PostResponse);
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "%a:%d Failed to POST payload to Redfish service.\n", __func__, __LINE__));
-
- DEBUG_CODE_BEGIN ();
- DEBUG ((DEBUG_ERROR, "%a: Request:\n", __func__));
- DumpRedfishPayload (DEBUG_ERROR, Payload);
- DEBUG ((DEBUG_ERROR, "%a: Response:\n", __func__));
- DumpRedfishResponse (__func__, DEBUG_ERROR, &PostResponse);
- DEBUG_CODE_END ();
-
- goto EXIT_FREE_JSON_VALUE;
- }
-
- //
- // per Redfish spec. the URL of new resource will be returned in "Location" header.
- //
- Status = GetEtagAndLocation (&PostResponse, Etag, Location);
- if (EFI_ERROR (Status)) {
- Status = EFI_DEVICE_ERROR;
- }
-
- RedfishFreeResponse (
- PostResponse.StatusCode,
- PostResponse.HeaderCount,
- PostResponse.Headers,
- PostResponse.Payload
- );
-
- RedfishCleanupPayload (Payload);
-
-EXIT_FREE_JSON_VALUE:
- JsonValueFree (ResourceJsonValue);
-
- return Status;
-}
-
/**
Return redfish URI by given config language. It's call responsibility to release returned buffer.
@@ -2191,7 +1976,7 @@ GetConfigureLang (
**/
EFI_STATUS
-RedfisSetRedfishUri (
+RedfishSetRedfishUri (
IN EFI_STRING ConfigLang,
IN EFI_STRING Uri
)
diff --git a/RedfishClientPkg/Library/RedfishHttpLib/RedfishHttpLib.c b/RedfishClientPkg/Library/RedfishHttpLib/RedfishHttpLib.c
new file mode 100644
index 000000000..433e85741
--- /dev/null
+++ b/RedfishClientPkg/Library/RedfishHttpLib/RedfishHttpLib.c
@@ -0,0 +1,299 @@
+/** @file
+ Redfish HTTP cache library helps Redfish application to get Redfish resource
+ from BMC with cache mechanism enabled.
+
+ Copyright (c) 2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include
+#include
+#include
+#include
+#include
+
+EDKII_REDFISH_HTTP_PROTOCOL *mRedfishHttpProtocol = NULL;
+
+/**
+ This function free resources in Response. Response is no longer available
+ after this function returns successfully.
+
+ @param[in] Response HTTP response to be released.
+
+ @retval EFI_SUCCESS Resrouce is released successfully.
+ @retval Others Errors occur.
+
+**/
+EFI_STATUS
+RedfishHttpFreeResource (
+ IN REDFISH_RESPONSE *Response
+ )
+{
+ if (mRedfishHttpProtocol == NULL) {
+ return EFI_NOT_READY;
+ }
+
+ return mRedfishHttpProtocol->FreeResponse (
+ mRedfishHttpProtocol,
+ Response
+ );
+}
+
+/**
+ Get redfish resource from given resource URI with cache mechanism
+ supported. It's caller's responsibility to Response by calling
+ RedfishHttpFreeResource ().
+
+ @param[in] Service Redfish service instance to make query.
+ @param[in] Uri Target resource URI.
+ @param[out] Response HTTP response from redfish service.
+ @param[in] UseCache If it is TRUE, this function will search for
+ cache first. If it is FALSE, this function
+ will query Redfish URI directly.
+
+ @retval EFI_SUCCESS Resrouce is returned successfully.
+ @retval Others Errors occur.
+
+**/
+EFI_STATUS
+RedfishHttpGetResource (
+ IN REDFISH_SERVICE Service,
+ IN EFI_STRING Uri,
+ OUT REDFISH_RESPONSE *Response,
+ IN BOOLEAN UseCache
+ )
+{
+ if (mRedfishHttpProtocol == NULL) {
+ return EFI_NOT_READY;
+ }
+
+ return mRedfishHttpProtocol->GetResource (
+ mRedfishHttpProtocol,
+ Service,
+ Uri,
+ Response,
+ UseCache
+ );
+}
+
+/**
+ This function expire the cached response of given URI.
+
+ @param[in] Uri Target response of URI.
+
+ @retval EFI_SUCCESS Target response is expired successfully.
+ @retval Others Errors occur.
+
+**/
+EFI_STATUS
+RedfishHttpExpireResponse (
+ IN EFI_STRING Uri
+ )
+{
+ if (mRedfishHttpProtocol == NULL) {
+ return EFI_NOT_READY;
+ }
+
+ return mRedfishHttpProtocol->ExpireResponse (
+ mRedfishHttpProtocol,
+ Uri
+ );
+}
+
+/**
+ Perform HTTP PATCH to send redfish resource to given resource URI.
+ It's caller's responsibility to free Response by calling FreeResponse ().
+
+ @param[in] Service Redfish service instance to make query.
+ @param[in] Uri Target resource URI.
+ @param[in] Content Data to patch.
+ @param[out] Response HTTP response from redfish service.
+
+ @retval EFI_SUCCESS Resrouce is returned successfully.
+ @retval Others Errors occur.
+
+**/
+EFI_STATUS
+RedfishHttpPatchResource (
+ IN REDFISH_SERVICE Service,
+ IN EFI_STRING Uri,
+ IN CHAR8 *Content,
+ OUT REDFISH_RESPONSE *Response
+ )
+{
+ if (mRedfishHttpProtocol == NULL) {
+ return EFI_NOT_READY;
+ }
+
+ return mRedfishHttpProtocol->PatchResource (
+ mRedfishHttpProtocol,
+ Service,
+ Uri,
+ Content,
+ Response
+ );
+}
+
+/**
+ Perform HTTP PUT to send redfish resource to given resource URI.
+ It's caller's responsibility to free Response by calling FreeResponse ().
+
+ @param[in] Service Redfish service instance to make query.
+ @param[in] Uri Target resource URI.
+ @param[in] Content Data to put.
+ @param[out] Response HTTP response from redfish service.
+
+ @retval EFI_SUCCESS Resrouce is returned successfully.
+ @retval Others Errors occur.
+
+**/
+EFI_STATUS
+RedfishHttpPutResource (
+ IN REDFISH_SERVICE Service,
+ IN EFI_STRING Uri,
+ IN CHAR8 *Content,
+ OUT REDFISH_RESPONSE *Response
+ )
+{
+ if (mRedfishHttpProtocol == NULL) {
+ return EFI_NOT_READY;
+ }
+
+ return mRedfishHttpProtocol->PutResource (
+ mRedfishHttpProtocol,
+ Service,
+ Uri,
+ Content,
+ Response
+ );
+}
+
+/**
+ Perform HTTP POST to send redfish resource to given resource URI.
+ It's caller's responsibility to free Response by calling FreeResponse ().
+
+ @param[in] Service Redfish service instance to make query.
+ @param[in] Uri Target resource URI.
+ @param[in] Content Data to post.
+ @param[out] Response HTTP response from redfish service.
+
+ @retval EFI_SUCCESS Resrouce is returned successfully.
+ @retval Others Errors occur.
+
+**/
+EFI_STATUS
+RedfishHttpPostResource (
+ IN REDFISH_SERVICE Service,
+ IN EFI_STRING Uri,
+ IN CHAR8 *Content,
+ OUT REDFISH_RESPONSE *Response
+ )
+{
+ if (mRedfishHttpProtocol == NULL) {
+ return EFI_NOT_READY;
+ }
+
+ return mRedfishHttpProtocol->PostResource (
+ mRedfishHttpProtocol,
+ Service,
+ Uri,
+ Content,
+ Response
+ );
+}
+
+/**
+ Perform HTTP DELETE to delete redfish resource on given resource URI.
+ It's caller's responsibility to free Response by calling FreeResponse ().
+
+ @param[in] Service Redfish service instance to make query.
+ @param[in] Uri Target resource URI.
+ @param[out] Response HTTP response from redfish service.
+
+ @retval EFI_SUCCESS Resrouce is returned successfully.
+ @retval Others Errors occur.
+
+**/
+EFI_STATUS
+RedfishHttpDeleteResource (
+ IN REDFISH_SERVICE Service,
+ IN EFI_STRING Uri,
+ OUT REDFISH_RESPONSE *Response
+ )
+{
+ if (mRedfishHttpProtocol == NULL) {
+ return EFI_NOT_READY;
+ }
+
+ return mRedfishHttpProtocol->DeleteResource (
+ mRedfishHttpProtocol,
+ Service,
+ Uri,
+ Response
+ );
+}
+
+/**
+ Callback function when gEdkIIRedfishHttpProtocolGuid is installed.
+
+ @param[in] Event Event whose notification function is being invoked.
+ @param[in] Context Pointer to the notification function's context.
+**/
+VOID
+EFIAPI
+RedfishHttpProtocolIsReady (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ EFI_STATUS Status;
+
+ if (mRedfishHttpProtocol != NULL) {
+ gBS->CloseEvent (Event);
+ return;
+ }
+
+ Status = gBS->LocateProtocol (
+ &gEdkIIRedfishHttpProtocolGuid,
+ NULL,
+ (VOID **)&mRedfishHttpProtocol
+ );
+ if (EFI_ERROR (Status)) {
+ return;
+ }
+
+ gBS->CloseEvent (Event);
+}
+
+/**
+
+ Initial HTTP library instance.
+
+ @param[in] ImageHandle The image handle.
+ @param[in] SystemTable The system table.
+
+ @retval EFI_SUCCESS Initial library successfully.
+ @retval Other Return error status.
+
+**/
+EFI_STATUS
+EFIAPI
+RedfishHttpConstructor (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ VOID *Registration;
+
+ EfiCreateProtocolNotifyEvent (
+ &gEdkIIRedfishHttpProtocolGuid,
+ TPL_CALLBACK,
+ RedfishHttpProtocolIsReady,
+ NULL,
+ &Registration
+ );
+
+ return EFI_SUCCESS;
+}
diff --git a/RedfishClientPkg/Library/RedfishHttpLib/RedfishHttpLib.inf b/RedfishClientPkg/Library/RedfishHttpLib/RedfishHttpLib.inf
new file mode 100644
index 000000000..cef888408
--- /dev/null
+++ b/RedfishClientPkg/Library/RedfishHttpLib/RedfishHttpLib.inf
@@ -0,0 +1,44 @@
+## @file
+# Redfish HTTP library is wrapper library for application to call Redfish
+# HTTP protocol easily.
+#
+# Copyright (c) 2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010006
+ BASE_NAME = RedfishHttpLib
+ FILE_GUID = 76FD14A1-D404-4FA9-8F3C-384FC8C09A82
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = RedfishHttpLib| DXE_DRIVER UEFI_DRIVER
+ CONSTRUCTOR = RedfishHttpConstructor
+
+#
+# VALID_ARCHITECTURES = IA32 X64 EBC
+#
+
+[Sources]
+ RedfishHttpLib.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ RedfishPkg/RedfishPkg.dec
+ RedfishClientPkg/RedfishClientPkg.dec
+
+[LibraryClasses]
+ BaseLib
+ DebugLib
+ UefiLib
+ UefiBootServicesTableLib
+
+[Protocols]
+ gEdkIIRedfishHttpProtocolGuid ## CONSUMES ##
+
+[depex]
+ TRUE
+
diff --git a/RedfishClientPkg/Library/RedfishVersionLib/RedfishVersionLib.c b/RedfishClientPkg/Library/RedfishVersionLib/RedfishVersionLib.c
index 45e156ca9..b47836818 100644
--- a/RedfishClientPkg/Library/RedfishVersionLib/RedfishVersionLib.c
+++ b/RedfishClientPkg/Library/RedfishVersionLib/RedfishVersionLib.c
@@ -2,6 +2,7 @@
Redfish version library implementation
(C) Copyright 2022 Hewlett Packard Enterprise Development LP
+ Copyright (c) 2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -10,15 +11,17 @@
#include
#include
#include
+#include
#include
#include
#include
#include
#include
#include
+#include
#define REDFISH_VERSION_DEFAULT_STRING L"v1"
-#define REDFISH_ROOT_URI "/redfish"
+#define REDFISH_ROOT_URI L"/redfish"
REDFISH_SERVICE *mCacheService;
EFI_STRING mVersionCache;
@@ -26,7 +29,7 @@ UINTN mVersionStringSize;
/**
Cache the redfish service version for later use so we don't have to query
- HTTP request everytime.
+ HTTP request every time.
@param[in] Service Redfish service instance
@param[in] Version Version string to cache
@@ -66,7 +69,7 @@ CacheVersion (
/**
Query HTTP request to BMC with given redfish service and return redfish
- version information. If there is troulbe to get Redfish version on BMC,
+ version information. If there is trouble to get Redfish version on BMC,
The value of PcdDefaultRedfishVersion is returned.
It's call responsibility to release returned buffer.
@@ -105,22 +108,17 @@ RedfishGetVersion (
//
// Get resource from redfish service.
//
- Status = RedfishGetByUri (
+ ZeroMem (&Response, sizeof (Response));
+ Status = RedfishHttpGetResource (
Service,
REDFISH_ROOT_URI,
- &Response
+ &Response,
+ TRUE
);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "%a, RedfishGetByService to %a failed: %r\n", __func__, REDFISH_ROOT_URI, Status));
if (Response.Payload != NULL) {
RedfishDumpPayload (Response.Payload);
- RedfishFreeResponse (
- NULL,
- 0,
- NULL,
- Response.Payload
- );
- Response.Payload = NULL;
}
goto ON_ERROR;
@@ -150,6 +148,10 @@ RedfishGetVersion (
VersionString = REDFISH_VERSION_DEFAULT_STRING;
}
+ if (Response.Payload != NULL) {
+ RedfishHttpFreeResource (&Response);
+ }
+
return AllocateCopyPool (StrSize (VersionString), VersionString);
}
diff --git a/RedfishClientPkg/Library/RedfishVersionLib/RedfishVersionLib.inf b/RedfishClientPkg/Library/RedfishVersionLib/RedfishVersionLib.inf
index 34d13d64f..eba8a0823 100644
--- a/RedfishClientPkg/Library/RedfishVersionLib/RedfishVersionLib.inf
+++ b/RedfishClientPkg/Library/RedfishVersionLib/RedfishVersionLib.inf
@@ -31,10 +31,11 @@
[LibraryClasses]
BaseLib
+ BaseMemoryLib
DebugLib
MemoryAllocationLib
PcdLib
- RedfishLib
+ RedfishHttpLib
JsonLib
[Protocols]
diff --git a/RedfishClientPkg/RedfishClient.fdf.inc b/RedfishClientPkg/RedfishClient.fdf.inc
index afa6555a7..5f89bc14c 100644
--- a/RedfishClientPkg/RedfishClient.fdf.inc
+++ b/RedfishClientPkg/RedfishClient.fdf.inc
@@ -15,6 +15,7 @@
INF RedfishClientPkg/RedfishFeatureCoreDxe/RedfishFeatureCoreDxe.inf
INF RedfishClientPkg/RedfishETagDxe/RedfishETagDxe.inf
INF RedfishClientPkg/RedfishConfigLangMapDxe/RedfishConfigLangMapDxe.inf
+ INF RedfishClientPkg/RedfishHttpDxe/RedfishHttpDxe.inf
INF RedfishClientPkg/Features/Memory/V1_7_1/Dxe/MemoryDxe.inf
INF RedfishClientPkg/Features/MemoryCollectionDxe/MemoryCollectionDxe.inf
INF RedfishClientPkg/Features/ComputerSystem/v1_5_0/Dxe/ComputerSystemDxe.inf
diff --git a/RedfishClientPkg/RedfishClientComponents.dsc.inc b/RedfishClientPkg/RedfishClientComponents.dsc.inc
index 0e27198af..0aa2a8082 100644
--- a/RedfishClientPkg/RedfishClientComponents.dsc.inc
+++ b/RedfishClientPkg/RedfishClientComponents.dsc.inc
@@ -17,6 +17,7 @@
RedfishClientPkg/RedfishFeatureCoreDxe/RedfishFeatureCoreDxe.inf
RedfishClientPkg/RedfishETagDxe/RedfishETagDxe.inf
RedfishClientPkg/RedfishConfigLangMapDxe/RedfishConfigLangMapDxe.inf
+ RedfishClientPkg/RedfishHttpDxe/RedfishHttpDxe.inf
RedfishClientPkg/HiiToRedfishMemoryDxe/HiiToRedfishMemoryDxe.inf
RedfishClientPkg/HiiToRedfishBootDxe/HiiToRedfishBootDxe.inf
RedfishClientPkg/HiiToRedfishBiosDxe/HiiToRedfishBiosDxe.inf
diff --git a/RedfishClientPkg/RedfishClientLibs.dsc.inc b/RedfishClientPkg/RedfishClientLibs.dsc.inc
index 5eae6711a..506635a7a 100644
--- a/RedfishClientPkg/RedfishClientLibs.dsc.inc
+++ b/RedfishClientPkg/RedfishClientLibs.dsc.inc
@@ -40,3 +40,4 @@
RedfishVersionLib|RedfishClientPkg/Library/RedfishVersionLib/RedfishVersionLib.inf
RedfishAddendumLib|RedfishClientPkg/Library/RedfishAddendumLib/RedfishAddendumLib.inf
RedfishDebugLib|RedfishPkg/Library/RedfishDebugLib/RedfishDebugLib.inf
+ RedfishHttpLib|RedfishClientPkg/Library/RedfishHttpLib/RedfishHttpLib.inf
diff --git a/RedfishClientPkg/RedfishClientPkg.dec b/RedfishClientPkg/RedfishClientPkg.dec
index eccbc22ef..3e8abe947 100644
--- a/RedfishClientPkg/RedfishClientPkg.dec
+++ b/RedfishClientPkg/RedfishClientPkg.dec
@@ -26,6 +26,7 @@
EdkIIRedfishResourceConfigLib|Include/Library/EdkIIRedfishResourceConfigLib.h
RedfishEventLib|Include/Library/RedfishEventLib.h
RedfishVersionLib|Include/Library/RedfishVersionLib.h
+ RedfishHttpLib|Include/Library/RedfishHttpLib.h
[LibraryClasses.Common.Private]
## @libraryclass Redfish Helper Library
@@ -45,6 +46,8 @@
gEdkIIRedfishFeatureInterchangeDataProtocolGuid = { 0x4B8FF71C, 0x4A7B, 0x9478, { 0xB7, 0x81, 0x35, 0x9B, 0x0A, 0xF2, 0x00, 0x91 } }
## Include/Protocol/EdkIIRedfishResourceAddendumProtocol.h
gEdkIIRedfishResourceAddendumProtocolGuid = { 0xda36b12b, 0xaad4, 0x4e90, { 0xba, 0xcb, 0xe3, 0xb5, 0x3b, 0x08, 0xbc, 0x54 } }
+ ## Include/Protocol/EdkIIRedfishHttpProtocol.h
+ gEdkIIRedfishHttpProtocolGuid = { 0xc3194dd2, 0xc796, 0x4abe, { 0xbd, 0x39, 0x9d, 0xf2, 0xe0, 0x4b, 0x86, 0xbc } }
[Guids]
## Include/Guid/RedfishClientPkgTokenSpace.h
@@ -73,6 +76,20 @@
gEfiRedfishClientPkgTokenSpaceGuid.PcdDefaultRedfishVersion|L"v1"|VOID*|0x10000004
## The number of seconds that the firmware will wait before system reboot
gEfiRedfishClientPkgTokenSpaceGuid.PcdRedfishSystemRebootTimeout|5|UINT16|0x20000002
+ ## The number of retry when HTTP GET request failed. If the value is 0, there is no retry enabled.
+ gEfiRedfishClientPkgTokenSpaceGuid.PcdHttpGetRetry|0|UINT16|0x20000003
+ ## The number of retry when HTTP PUT request failed. If the value is 0, there is no retry enabled.
+ gEfiRedfishClientPkgTokenSpaceGuid.PcdHttpPutRetry|0|UINT16|0x20000004
+ ## The number of retry when HTTP PATCH request failed. If the value is 0, there is no retry enabled.
+ gEfiRedfishClientPkgTokenSpaceGuid.PcdHttpPatchRetry|0|UINT16|0x20000005
+ ## The number of retry when HTTP POST request failed. If the value is 0, there is no retry enabled.
+ gEfiRedfishClientPkgTokenSpaceGuid.PcdHttpPostRetry|0|UINT16|0x20000006
+ ## The number of retry when HTTP DELETE request failed. If the value is 0, there is no retry enabled.
+ gEfiRedfishClientPkgTokenSpaceGuid.PcdHttpDeleteRetry|0|UINT16|0x20000007
+ ## The number of second to wait before driver retry HTTP request. If the value is 0, there is no wait before next retry.
+ gEfiRedfishClientPkgTokenSpaceGuid.PcdHttpRetryWaitInSecond|1|UINT16|0x20000008
+ ## This is used to disable Redfish HTTP cache function and every request will be sent to Redfish service.
+ gEfiRedfishClientPkgTokenSpaceGuid.PcdHttpCacheDisabled|FALSE|BOOLEAN|0x20000009
[PcdsDynamicEx]
## The flag used to indicate that system reboot is required due to system configuration change
diff --git a/RedfishClientPkg/RedfishClientPkg.dsc b/RedfishClientPkg/RedfishClientPkg.dsc
index e16c91b83..6eb706530 100644
--- a/RedfishClientPkg/RedfishClientPkg.dsc
+++ b/RedfishClientPkg/RedfishClientPkg.dsc
@@ -61,5 +61,6 @@
RedfishClientPkg/Library/RedfishFeatureUtilityLib/RedfishFeatureUtilityLib.inf
RedfishClientPkg/PrivateLibrary/RedfishLib/RedfishLib.inf
RedfishClientPkg/Library/RedfishAddendumLib/RedfishAddendumLib.inf
+ RedfishClientPkg/Library/RedfishHttpLib/RedfishHttpLib.inf
!include RedfishClientPkg/RedfishClient.dsc.inc
diff --git a/RedfishClientPkg/RedfishHttpDxe/RedfishHttpData.c b/RedfishClientPkg/RedfishHttpDxe/RedfishHttpData.c
new file mode 100644
index 000000000..733388c32
--- /dev/null
+++ b/RedfishClientPkg/RedfishHttpDxe/RedfishHttpData.c
@@ -0,0 +1,449 @@
+/** @file
+ RedfishHttpDxe produces EdkIIRedfishHttpProtocol
+ for EDK2 Redfish Feature driver to do HTTP operations.
+
+ Copyright (c) 2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "RedfishHttpData.h"
+
+/**
+ This function copy the data in SrcResponse to DstResponse.
+
+ @param[in] SrcResponse Source Response to copy.
+ @param[out] DstResponse Destination Response.
+
+ @retval EFI_SUCCESS Response is copied successfully.
+ @retval Others Error occurs.
+
+**/
+EFI_STATUS
+CopyRedfishResponse (
+ IN REDFISH_RESPONSE *SrcResponse,
+ OUT REDFISH_RESPONSE *DstResponse
+ )
+{
+ EDKII_JSON_VALUE JsonValue;
+ REDFISH_SERVICE Service;
+ UINTN Index;
+
+ if ((SrcResponse == NULL) || (DstResponse == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (SrcResponse == DstResponse) {
+ return EFI_SUCCESS;
+ }
+
+ //
+ // Status code
+ //
+ if (SrcResponse->StatusCode != NULL) {
+ DstResponse->StatusCode = AllocateCopyPool (sizeof (EFI_HTTP_STATUS_CODE), SrcResponse->StatusCode);
+ if (DstResponse->StatusCode == NULL) {
+ goto ON_ERROR;
+ }
+ }
+
+ //
+ // Header
+ //
+ if ((SrcResponse->HeaderCount > 0) && (SrcResponse->Headers != NULL)) {
+ DstResponse->HeaderCount = 0;
+ DstResponse->Headers = AllocateZeroPool (sizeof (EFI_HTTP_HEADER) * SrcResponse->HeaderCount);
+ if (DstResponse->Headers == NULL) {
+ goto ON_ERROR;
+ }
+
+ for (Index = 0; Index < SrcResponse->HeaderCount; Index++) {
+ DstResponse->Headers[Index].FieldName = AllocateCopyPool (AsciiStrSize (SrcResponse->Headers[Index].FieldName), SrcResponse->Headers[Index].FieldName);
+ if (DstResponse->Headers[Index].FieldName == NULL) {
+ goto ON_ERROR;
+ }
+
+ DstResponse->Headers[Index].FieldValue = AllocateCopyPool (AsciiStrSize (SrcResponse->Headers[Index].FieldValue), SrcResponse->Headers[Index].FieldValue);
+ if (DstResponse->Headers[Index].FieldValue == NULL) {
+ goto ON_ERROR;
+ }
+
+ DstResponse->HeaderCount += 1;
+ }
+ }
+
+ //
+ // Payload
+ //
+ if (SrcResponse->Payload != NULL) {
+ Service = RedfishServiceInPayload (SrcResponse->Payload);
+ JsonValue = RedfishJsonInPayload (SrcResponse->Payload);
+ DstResponse->Payload = RedfishCreatePayload (JsonValue, Service);
+ if (DstResponse->Payload == NULL) {
+ goto ON_ERROR;
+ }
+ }
+
+ return EFI_SUCCESS;
+
+ON_ERROR:
+
+ RedfishFreeResponse (
+ DstResponse->StatusCode,
+ DstResponse->HeaderCount,
+ DstResponse->Headers,
+ DstResponse->Payload
+ );
+
+ return EFI_OUT_OF_RESOURCES;
+}
+
+/**
+ This function clone input response and return to caller
+
+ @param[in] Response Response to clone.
+
+ @retval REDFISH_RESPONSE * Response is cloned.
+ @retval NULL Errors occur.
+
+**/
+REDFISH_RESPONSE *
+CloneRedfishResponse (
+ IN REDFISH_RESPONSE *Response
+ )
+{
+ EFI_STATUS Status;
+ REDFISH_RESPONSE *NewResponse;
+
+ if (Response == NULL) {
+ return NULL;
+ }
+
+ NewResponse = AllocateZeroPool (sizeof (REDFISH_RESPONSE));
+ if (NewResponse == NULL) {
+ return NULL;
+ }
+
+ Status = CopyRedfishResponse (Response, NewResponse);
+ if (EFI_ERROR (Status)) {
+ FreePool (NewResponse);
+ return NULL;
+ }
+
+ return NewResponse;
+}
+
+/**
+ Release REDFISH_HTTP_CACHE_DATA resource
+
+ @param[in] Data Pointer to REDFISH_HTTP_CACHE_DATA instance
+
+ @retval EFI_SUCCESS REDFISH_HTTP_CACHE_DATA is released successfully.
+ @retval EFI_INVALID_PARAMETER Data is NULL
+
+**/
+EFI_STATUS
+ReleaseHttpCacheData (
+ IN REDFISH_HTTP_CACHE_DATA *Data
+ )
+{
+ if (Data == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (Data->Uri != NULL) {
+ FreePool (Data->Uri);
+ }
+
+ if (Data->Response != NULL) {
+ if (Data->Response->Payload != NULL) {
+ RedfishFreeResponse (
+ Data->Response->StatusCode,
+ Data->Response->HeaderCount,
+ Data->Response->Headers,
+ Data->Response->Payload
+ );
+ FreePool (Data->Response);
+ }
+ }
+
+ FreePool (Data);
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Create new cache data.
+
+ @param[in] Uri The URI string matching to this cache data.
+ @param[in] Response HTTP response.
+
+ @retval REDFISH_HTTP_CACHE_DATA * Pointer to newly created cache data.
+ @retval NULL No memory available.
+
+**/
+REDFISH_HTTP_CACHE_DATA *
+NewHttpCacheData (
+ IN EFI_STRING Uri,
+ IN REDFISH_RESPONSE *Response
+ )
+{
+ REDFISH_HTTP_CACHE_DATA *NewData;
+ UINTN Size;
+
+ if (IS_EMPTY_STRING (Uri) || (Response == NULL)) {
+ return NULL;
+ }
+
+ NewData = AllocateZeroPool (sizeof (REDFISH_HTTP_CACHE_DATA));
+ if (NewData == NULL) {
+ return NULL;
+ }
+
+ Size = StrSize (Uri);
+ NewData->Uri = AllocateCopyPool (Size, Uri);
+ if (NewData->Uri == NULL) {
+ goto ON_ERROR;
+ }
+
+ NewData->Response = Response;
+ NewData->HitCount = 1;
+
+ return NewData;
+
+ON_ERROR:
+
+ if (NewData != NULL) {
+ ReleaseHttpCacheData (NewData);
+ }
+
+ return NULL;
+}
+
+/**
+ Search on given ListHeader for given URI string.
+
+ @param[in] ListHeader Target list to search.
+ @param[in] Uri Target URI to search.
+
+ @retval REDFISH_HTTP_CACHE_DATA Target cache data is found.
+ @retval NULL No cache data with given URI is found.
+
+**/
+REDFISH_HTTP_CACHE_DATA *
+FindHttpCacheData (
+ IN LIST_ENTRY *ListHeader,
+ IN EFI_STRING Uri
+ )
+{
+ LIST_ENTRY *List;
+ REDFISH_HTTP_CACHE_DATA *Data;
+
+ if (IS_EMPTY_STRING (Uri)) {
+ return NULL;
+ }
+
+ if (IsListEmpty (ListHeader)) {
+ return NULL;
+ }
+
+ Data = NULL;
+ List = GetFirstNode (ListHeader);
+ while (!IsNull (ListHeader, List)) {
+ Data = REDFISH_HTTP_CACHE_FROM_LIST (List);
+
+ if (StrCmp (Data->Uri, Uri) == 0) {
+ return Data;
+ }
+
+ List = GetNextNode (ListHeader, List);
+ }
+
+ return NULL;
+}
+
+/**
+ Search on given ListHeader and return cache data with minimum hit count.
+
+ @param[in] ListHeader Target list to search.
+
+ @retval REDFISH_HTTP_CACHE_DATA Target cache data is returned.
+ @retval NULL No cache data is found.
+
+**/
+REDFISH_HTTP_CACHE_DATA *
+FindUnusedHttpCacheData (
+ IN LIST_ENTRY *ListHeader
+ )
+{
+ LIST_ENTRY *List;
+ REDFISH_HTTP_CACHE_DATA *Data;
+ REDFISH_HTTP_CACHE_DATA *UnusedData;
+ UINTN HitCount;
+
+ if (IsListEmpty (ListHeader)) {
+ return NULL;
+ }
+
+ Data = NULL;
+ UnusedData = NULL;
+ HitCount = 0;
+
+ List = GetFirstNode (ListHeader);
+ Data = REDFISH_HTTP_CACHE_FROM_LIST (List);
+ UnusedData = Data;
+ HitCount = Data->HitCount;
+ List = GetNextNode (ListHeader, List);
+
+ while (!IsNull (ListHeader, List)) {
+ Data = REDFISH_HTTP_CACHE_FROM_LIST (List);
+
+ if (Data->HitCount < HitCount) {
+ HitCount = Data->HitCount;
+ UnusedData = Data;
+ }
+
+ List = GetNextNode (ListHeader, List);
+ }
+
+ return UnusedData;
+}
+
+/**
+ Delete a cache data by given cache instance.
+
+ @param[in] List Target cache list to be removed.
+ @param[in] Data Pointer to the instance to be deleted.
+
+ @retval EFI_SUCCESS Cache data is removed.
+ @retval Others Fail to remove cache data.
+
+**/
+EFI_STATUS
+DeleteHttpCacheData (
+ IN REDFISH_HTTP_CACHE_LIST *List,
+ IN REDFISH_HTTP_CACHE_DATA *Data
+ )
+{
+ if ((List == NULL) || (Data == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ DEBUG ((REDFISH_HTTP_CACHE_DEBUG, "%a: delete: %s\n", __func__, Data->Uri));
+
+ RemoveEntryList (&Data->List);
+ --List->Count;
+
+ return ReleaseHttpCacheData (Data);
+}
+
+/**
+ Add new cache by given URI and HTTP response to specify List.
+
+ @param[in] List Target cache list to add.
+ @param[in] Uri The URI string matching to this cache data.
+ @param[in] Response HTTP response.
+
+ @retval EFI_SUCCESS Cache data is added.
+ @retval Others Fail to add cache data.
+
+**/
+EFI_STATUS
+AddHttpCacheData (
+ IN REDFISH_HTTP_CACHE_LIST *List,
+ IN EFI_STRING Uri,
+ IN REDFISH_RESPONSE *Response
+ )
+{
+ REDFISH_HTTP_CACHE_DATA *NewData;
+ REDFISH_HTTP_CACHE_DATA *OldData;
+ REDFISH_HTTP_CACHE_DATA *UnusedData;
+ REDFISH_RESPONSE *NewResponse;
+
+ if ((List == NULL) || IS_EMPTY_STRING (Uri) || (Response == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // If same cache data exist, replace it with latest one.
+ //
+ OldData = FindHttpCacheData (&List->Head, Uri);
+ if (OldData != NULL) {
+ DeleteHttpCacheData (List, OldData);
+ }
+
+ //
+ // Check capacity
+ //
+ if (List->Count >= List->Capacity) {
+ DEBUG ((REDFISH_HTTP_CACHE_DEBUG, "%a: list is full and retire unused cache\n", __func__));
+ UnusedData = FindUnusedHttpCacheData (&List->Head);
+ if (UnusedData == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ DeleteHttpCacheData (List, UnusedData);
+ }
+
+ //
+ // Clone a local copy
+ //
+ NewResponse = CloneRedfishResponse (Response);
+ if (NewResponse == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ NewData = NewHttpCacheData (Uri, NewResponse);
+ if (NewData == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ InsertTailList (&List->Head, &NewData->List);
+ ++List->Count;
+
+ DEBUG ((REDFISH_HTTP_CACHE_DEBUG, "%a: cache(%d/%d) %s\n", __func__, List->Count, List->Capacity, NewData->Uri));
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Release all cache from list.
+
+ @param[in] CacheList The list to be released.
+
+ @retval EFI_SUCCESS All cache data are released.
+ @retval EFI_INVALID_PARAMETER CacheList is NULL.
+
+**/
+EFI_STATUS
+ReleaseCacheList (
+ IN REDFISH_HTTP_CACHE_LIST *CacheList
+ )
+{
+ LIST_ENTRY *List;
+ LIST_ENTRY *Next;
+ REDFISH_HTTP_CACHE_DATA *Data;
+
+ if (CacheList == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (IsListEmpty (&CacheList->Head)) {
+ return EFI_SUCCESS;
+ }
+
+ Data = NULL;
+ Next = NULL;
+ List = GetFirstNode (&CacheList->Head);
+ while (!IsNull (&CacheList->Head, List)) {
+ Data = REDFISH_HTTP_CACHE_FROM_LIST (List);
+ Next = GetNextNode (&CacheList->Head, List);
+
+ DeleteHttpCacheData (CacheList, Data);
+
+ List = Next;
+ }
+
+ return EFI_SUCCESS;
+}
diff --git a/RedfishClientPkg/RedfishHttpDxe/RedfishHttpData.h b/RedfishClientPkg/RedfishHttpDxe/RedfishHttpData.h
new file mode 100644
index 000000000..35f86468c
--- /dev/null
+++ b/RedfishClientPkg/RedfishHttpDxe/RedfishHttpData.h
@@ -0,0 +1,141 @@
+/** @file
+ Definitions of RedfishHttpData
+
+ Copyright (c) 2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef EDKII_REDFISH_HTTP_DATA_H_
+#define EDKII_REDFISH_HTTP_DATA_H_
+
+#include "RedfishHttpDxe.h"
+
+///
+/// Definition of REDFISH_HTTP_CACHE_DATA
+///
+typedef struct {
+ LIST_ENTRY List;
+ EFI_STRING Uri;
+ UINTN HitCount;
+ REDFISH_RESPONSE *Response;
+} REDFISH_HTTP_CACHE_DATA;
+
+#define REDFISH_HTTP_CACHE_FROM_LIST(a) BASE_CR (a, REDFISH_HTTP_CACHE_DATA, List)
+
+///
+/// Definition of REDFISH_HTTP_CACHE_LIST
+///
+typedef struct {
+ LIST_ENTRY Head;
+ UINTN Count;
+ UINTN Capacity;
+} REDFISH_HTTP_CACHE_LIST;
+
+///
+/// Definition of REDFISH_HTTP_RETRY_SETTING
+///
+typedef struct {
+ UINT16 MaximumRetryGet;
+ UINT16 MaximumRetryPut;
+ UINT16 MaximumRetryPost;
+ UINT16 MaximumRetryPatch;
+ UINT16 MaximumRetryDelete;
+ UINTN RetryWait;
+} REDFISH_HTTP_RETRY_SETTING;
+
+///
+/// Definition of REDFISH_HTTP_CACHE_PRIVATE
+///
+typedef struct {
+ EFI_HANDLE ImageHandle;
+ BOOLEAN CacheDisabled;
+ REDFISH_HTTP_CACHE_LIST CacheList;
+ EDKII_REDFISH_HTTP_PROTOCOL Protocol;
+ REDFISH_HTTP_RETRY_SETTING RetrySetting;
+} REDFISH_HTTP_CACHE_PRIVATE;
+
+#define REDFISH_HTTP_CACHE_PRIVATE_FROM_THIS(a) BASE_CR (a, REDFISH_HTTP_CACHE_PRIVATE, Protocol)
+
+/**
+ Search on given ListHeader for given URI string.
+
+ @param[in] ListHeader Target list to search.
+ @param[in] Uri Target URI to search.
+
+ @retval REDFISH_HTTP_CACHE_DATA Target cache data is found.
+ @retval NULL No cache data with given URI is found.
+
+**/
+REDFISH_HTTP_CACHE_DATA *
+FindHttpCacheData (
+ IN LIST_ENTRY *ListHeader,
+ IN EFI_STRING Uri
+ );
+
+/**
+ This function copy the data in SrcResponse to DstResponse.
+
+ @param[in] SrcResponse Source Response to copy.
+ @param[out] DstResponse Destination Response.
+
+ @retval EFI_SUCCESS Response is copied successfully.
+ @retval Others Error occurs.
+
+**/
+EFI_STATUS
+CopyRedfishResponse (
+ IN REDFISH_RESPONSE *SrcResponse,
+ OUT REDFISH_RESPONSE *DstResponse
+ );
+
+/**
+ Release all cache from list.
+
+ @param[in] CacheList The list to be released.
+
+ @retval EFI_SUCCESS All cache data are released.
+ @retval EFI_INVALID_PARAMETER CacheList is NULL.
+
+**/
+EFI_STATUS
+ReleaseCacheList (
+ IN REDFISH_HTTP_CACHE_LIST *CacheList
+ );
+
+/**
+ Add new cache by given URI and HTTP response to specify List.
+
+ @param[in] List Target cache list to add.
+ @param[in] Uri The URI string matching to this cache data.
+ @param[in] Response HTTP response.
+
+ @retval EFI_SUCCESS Cache data is added.
+ @retval Others Fail to add cache data.
+
+**/
+EFI_STATUS
+AddHttpCacheData (
+ IN REDFISH_HTTP_CACHE_LIST *List,
+ IN EFI_STRING Uri,
+ IN REDFISH_RESPONSE *Response
+ );
+
+/**
+ Delete a cache data by given cache instance.
+
+ @param[in] List Target cache list to be removed.
+ @param[in] Data Pointer to the instance to be deleted.
+
+ @retval EFI_SUCCESS Cache data is removed.
+ @retval Others Fail to remove cache data.
+
+**/
+EFI_STATUS
+DeleteHttpCacheData (
+ IN REDFISH_HTTP_CACHE_LIST *List,
+ IN REDFISH_HTTP_CACHE_DATA *Data
+ );
+
+#endif
diff --git a/RedfishClientPkg/RedfishHttpDxe/RedfishHttpDxe.c b/RedfishClientPkg/RedfishHttpDxe/RedfishHttpDxe.c
new file mode 100644
index 000000000..a08a25c3d
--- /dev/null
+++ b/RedfishClientPkg/RedfishHttpDxe/RedfishHttpDxe.c
@@ -0,0 +1,986 @@
+/** @file
+ RedfishHttpDxe produces EdkIIRedfishHttpProtocol
+ for EDK2 Redfish Feature driver to do HTTP operations.
+
+ Copyright (c) 2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "RedfishHttpDxe.h"
+#include "RedfishHttpData.h"
+
+REDFISH_HTTP_CACHE_PRIVATE *mRedfishHttpCachePrivate = NULL;
+
+/**
+ Debug output the cache list.
+
+ @param[in] Msg Debug message string.
+ @param[in] ErrorLevel Output error level.
+ @param[in] CacheList Target list to dump.
+
+ @retval EFI_SUCCESS Debug dump finished.
+ @retval EFI_INVALID_PARAMETER HttpCacheList is NULL.
+
+**/
+EFI_STATUS
+DumpHttpCacheList (
+ IN CONST CHAR8 *Msg,
+ IN UINTN ErrorLevel,
+ IN REDFISH_HTTP_CACHE_LIST *CacheList
+ )
+{
+ LIST_ENTRY *List;
+ REDFISH_HTTP_CACHE_DATA *Data;
+ UINTN Index;
+
+ if (CacheList == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (!IS_EMPTY_STRING (Msg)) {
+ DEBUG ((ErrorLevel, "%a\n", Msg));
+ }
+
+ if (IsListEmpty (&CacheList->Head)) {
+ DEBUG ((ErrorLevel, "list is empty\n"));
+ return EFI_NOT_FOUND;
+ }
+
+ DEBUG ((ErrorLevel, "list count: %d capacity: %d\n", CacheList->Count, CacheList->Capacity));
+ Data = NULL;
+ Index = 0;
+ List = GetFirstNode (&CacheList->Head);
+ while (!IsNull (&CacheList->Head, List)) {
+ Data = REDFISH_HTTP_CACHE_FROM_LIST (List);
+
+ DEBUG ((ErrorLevel, "%d) Uri: %s Hit: %d\n", ++Index, Data->Uri, Data->HitCount));
+
+ List = GetNextNode (&CacheList->Head, List);
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+
+ Check HTTP status code to see if we like to retry HTTP request or not.
+
+ @param[in] StatusCode HTTP status code.
+
+ @retval BOOLEAN Return true when we like to retry request.
+ Return false when we don't want to retry request.
+
+**/
+BOOLEAN
+RedfishRetryRequired (
+ IN EFI_HTTP_STATUS_CODE *StatusCode
+ )
+{
+ if (StatusCode == NULL) {
+ return TRUE;
+ }
+
+ if ((*StatusCode == HTTP_STATUS_500_INTERNAL_SERVER_ERROR) ||
+ (*StatusCode == HTTP_STATUS_UNSUPPORTED_STATUS))
+ {
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+/**
+
+ Convert Unicode string to ASCII string. It's call responsibility to release returned buffer.
+
+ @param[in] UnicodeStr Unicode string to convert.
+
+ @retval CHAR8 * ASCII string returned.
+ @retval NULL Errors occur.
+
+**/
+CHAR8 *
+StringUnicodeToAscii (
+ IN EFI_STRING UnicodeStr
+ )
+{
+ CHAR8 *AsciiStr;
+ UINTN AsciiStrSize;
+ EFI_STATUS Status;
+
+ if (IS_EMPTY_STRING (UnicodeStr)) {
+ return NULL;
+ }
+
+ AsciiStrSize = StrLen (UnicodeStr) + 1;
+ AsciiStr = AllocatePool (AsciiStrSize);
+ if (AsciiStr == NULL) {
+ return NULL;
+ }
+
+ Status = UnicodeStrToAsciiStrS (UnicodeStr, AsciiStr, AsciiStrSize);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "UnicodeStrToAsciiStrS failed: %r\n", Status));
+ FreePool (AsciiStr);
+ return NULL;
+ }
+
+ return AsciiStr;
+}
+
+/**
+ Return HTTP method in ASCII string. Caller does not need
+ to free returned string buffer.
+
+ @param[in] Method HTTP method.
+
+ @retval CHAR8 * Method in string.
+**/
+CHAR8 *
+HttpMethodToString (
+ IN EFI_HTTP_METHOD Method
+ )
+{
+ switch (Method) {
+ case HttpMethodGet:
+ return HTTP_METHOD_GET;
+ break;
+ case HttpMethodPost:
+ return HTTP_METHOD_POST;
+ break;
+ case HttpMethodPatch:
+ return HTTP_METHOD_PATCH;
+ break;
+ case HttpMethodPut:
+ return HTTP_METHOD_PUT;
+ break;
+ case HttpMethodDelete:
+ return HTTP_METHOD_DELETE;
+ break;
+ default:
+ break;
+ }
+
+ return "Unknown";
+}
+
+/**
+ Report HTTP communication error via report status code.
+
+ @param[in] Method HTTP method.
+ @param[in] Uri The URI which has failure.
+ @param[in] HttpStatusCode HTTP status code.
+
+**/
+VOID
+ReportHttpError (
+ IN EFI_HTTP_METHOD Method,
+ IN CHAR8 *Uri,
+ IN EFI_HTTP_STATUS_CODE *HttpStatusCode OPTIONAL
+ )
+{
+ CHAR8 ErrorMsg[REDFISH_ERROR_MSG_MAX];
+
+ if (IS_EMPTY_STRING (Uri)) {
+ DEBUG ((DEBUG_ERROR, "%a: no URI to report error status\n", __func__));
+ return;
+ }
+
+ //
+ // Report failure of URI and HTTP status code.
+ //
+ AsciiSPrint (ErrorMsg, sizeof (ErrorMsg), REDFISH_HTTP_ERROR_REPORT, HttpMethodToString (Method), (HttpStatusCode == NULL ? HTTP_STATUS_UNSUPPORTED_STATUS : *HttpStatusCode), Uri);
+
+ REPORT_STATUS_CODE_WITH_EXTENDED_DATA (
+ EFI_ERROR_CODE | EFI_ERROR_MAJOR,
+ EFI_COMPUTING_UNIT_MANAGEABILITY | EFI_MANAGEABILITY_EC_REDFISH_COMMUNICATION_ERROR,
+ ErrorMsg,
+ AsciiStrSize (ErrorMsg)
+ );
+}
+
+/**
+ Perform HTTP GET to Get redfish resource from given resource URI with
+ cache mechanism supported. It's caller's responsibility to free Response
+ by calling FreeResponse ().
+
+ @param[in] This Pointer to EDKII_REDFISH_HTTP_PROTOCOL instance.
+ @param[in] Service Redfish service instance to make query.
+ @param[in] Uri Target resource URI.
+ @param[out] Response HTTP response from redfish service.
+ @param[in] UseCache If it is TRUE, this function will search for
+ cache first. If it is FALSE, this function
+ will query Redfish URI directly.
+
+ @retval EFI_SUCCESS Resrouce is returned successfully.
+ @retval Others Errors occur.
+
+**/
+EFI_STATUS
+EFIAPI
+RedfishHttpGetResource (
+ IN EDKII_REDFISH_HTTP_PROTOCOL *This,
+ IN REDFISH_SERVICE Service,
+ IN EFI_STRING Uri,
+ OUT REDFISH_RESPONSE *Response,
+ IN BOOLEAN UseCache
+ )
+{
+ EFI_STATUS Status;
+ CHAR8 *AsciiUri;
+ REDFISH_HTTP_CACHE_DATA *CacheData;
+ UINTN RetryCount;
+ REDFISH_HTTP_CACHE_PRIVATE *Private;
+
+ if ((This == NULL) || (Service == NULL) || (Response == NULL) || IS_EMPTY_STRING (Uri)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ DEBUG ((REDFISH_HTTP_CACHE_DEBUG, "%a: Get URI: %s cache: %a\n", __func__, Uri, (UseCache ? "true" : "false")));
+
+ Private = REDFISH_HTTP_CACHE_PRIVATE_FROM_THIS (This);
+ AsciiUri = NULL;
+ CacheData = NULL;
+ RetryCount = 0;
+ ZeroMem (Response, sizeof (REDFISH_RESPONSE));
+
+ if (Private->CacheDisabled) {
+ UseCache = FALSE;
+ DEBUG ((REDFISH_HTTP_CACHE_DEBUG, "%a: cache is disabled by PCD!\n", __func__));
+ }
+
+ //
+ // Search for cache list.
+ //
+ if (UseCache) {
+ CacheData = FindHttpCacheData (&Private->CacheList.Head, Uri);
+ if (CacheData != NULL) {
+ DEBUG ((REDFISH_HTTP_CACHE_DEBUG_REQUEST, "%a: cache hit! %s\n", __func__, Uri));
+
+ //
+ // Copy cached response to caller's buffer.
+ //
+ Status = CopyRedfishResponse (CacheData->Response, Response);
+ CacheData->HitCount += 1;
+ return Status;
+ }
+ }
+
+ AsciiUri = StringUnicodeToAscii (Uri);
+ if (AsciiUri == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ //
+ // Get resource from redfish service.
+ //
+ do {
+ RetryCount += 1;
+ Status = RedfishGetByUri (
+ Service,
+ AsciiUri,
+ Response
+ );
+ DEBUG ((REDFISH_HTTP_CACHE_DEBUG_REQUEST, "%a: HTTP request: %a :%r\n", __func__, AsciiUri, Status));
+ if (!EFI_ERROR (Status) || (RetryCount >= Private->RetrySetting.MaximumRetryGet)) {
+ break;
+ }
+
+ //
+ // Retry when BMC is not ready.
+ //
+ if ((Response->StatusCode != NULL)) {
+ DEBUG_CODE (
+ DumpRedfishResponse (NULL, DEBUG_ERROR, Response);
+ );
+
+ if (!RedfishRetryRequired (Response->StatusCode)) {
+ break;
+ }
+
+ //
+ // Release response for next round of request.
+ //
+ This->FreeResponse (This, Response);
+ }
+
+ DEBUG ((DEBUG_WARN, "%a: RedfishGetByUri failed, retry (%d/%d)\n", __func__, RetryCount, Private->RetrySetting.MaximumRetryGet));
+ if (Private->RetrySetting.RetryWait > 0) {
+ gBS->Stall (Private->RetrySetting.RetryWait);
+ }
+ } while (TRUE);
+
+ if (EFI_ERROR (Status)) {
+ DEBUG_CODE (
+ DumpRedfishResponse (NULL, DEBUG_ERROR, Response);
+ );
+ //
+ // Report status code for Redfish failure
+ //
+ ReportHttpError (HttpMethodGet, AsciiUri, Response->StatusCode);
+ DEBUG ((DEBUG_ERROR, "%a: get %a failed (%d/%d): %r\n", __func__, AsciiUri, RetryCount, Private->RetrySetting.MaximumRetryGet, Status));
+ goto ON_RELEASE;
+ }
+
+ if (!Private->CacheDisabled) {
+ //
+ // Keep response in cache list
+ //
+ Status = AddHttpCacheData (&Private->CacheList, Uri, Response);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a: failed to cache %s: %r\n", __func__, Uri, Status));
+ goto ON_RELEASE;
+ }
+
+ DEBUG_CODE (
+ DumpHttpCacheList (__func__, REDFISH_HTTP_CACHE_DEBUG_DUMP, &Private->CacheList);
+ );
+ }
+
+ON_RELEASE:
+
+ if (AsciiUri != NULL) {
+ FreePool (AsciiUri);
+ }
+
+ return Status;
+}
+
+/**
+ This function free resources in given Response.
+
+ @param[in] This Pointer to EDKII_REDFISH_HTTP_PROTOCOL instance.
+ @param[in] Response HTTP response to be released.
+
+ @retval EFI_SUCCESS Resrouce is released successfully.
+ @retval Others Errors occur.
+
+**/
+EFI_STATUS
+EFIAPI
+RedfishHttpFreeResponse (
+ IN EDKII_REDFISH_HTTP_PROTOCOL *This,
+ IN REDFISH_RESPONSE *Response
+ )
+{
+ if ((This == NULL) || (Response == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ DEBUG ((REDFISH_HTTP_CACHE_DEBUG, "%a: entry\n", __func__));
+
+ //
+ // Call function in RedfishLib to release resource.
+ //
+ RedfishFreeResponse (
+ Response->StatusCode,
+ Response->HeaderCount,
+ Response->Headers,
+ Response->Payload
+ );
+
+ return EFI_SUCCESS;
+}
+
+/**
+ This function expire the cached response of given URI.
+
+ @param[in] This Pointer to EDKII_REDFISH_HTTP_PROTOCOL instance.
+ @param[in] Uri Target response of URI.
+
+ @retval EFI_SUCCESS Target response is expired successfully.
+ @retval Others Errors occur.
+
+**/
+EFI_STATUS
+EFIAPI
+RedfishHttpExpireResponse (
+ IN EDKII_REDFISH_HTTP_PROTOCOL *This,
+ IN EFI_STRING Uri
+ )
+{
+ REDFISH_HTTP_CACHE_PRIVATE *Private;
+ REDFISH_HTTP_CACHE_DATA *CacheData;
+
+ if ((This == NULL) || IS_EMPTY_STRING (Uri)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ DEBUG ((REDFISH_HTTP_CACHE_DEBUG, "%a: expire URI: %s\n", __func__, Uri));
+
+ Private = REDFISH_HTTP_CACHE_PRIVATE_FROM_THIS (This);
+
+ CacheData = FindHttpCacheData (&Private->CacheList.Head, Uri);
+ if (CacheData == NULL) {
+ return EFI_NOT_FOUND;
+ }
+
+ return DeleteHttpCacheData (&Private->CacheList, CacheData);
+}
+
+/**
+ Perform HTTP PATCH to send redfish resource to given resource URI.
+ It's caller's responsibility to free Response by calling FreeResponse ().
+
+ @param[in] This Pointer to EDKII_REDFISH_HTTP_PROTOCOL instance.
+ @param[in] Service Redfish service instance to make query.
+ @param[in] Uri Target resource URI.
+ @param[in] Content Data to patch.
+ @param[out] Response HTTP response from redfish service.
+
+ @retval EFI_SUCCESS Resrouce is returned successfully.
+ @retval Others Errors occur.
+
+**/
+EFI_STATUS
+EFIAPI
+RedfishHttpPatchResource (
+ IN EDKII_REDFISH_HTTP_PROTOCOL *This,
+ IN REDFISH_SERVICE Service,
+ IN EFI_STRING Uri,
+ IN CHAR8 *Content,
+ OUT REDFISH_RESPONSE *Response
+ )
+{
+ EFI_STATUS Status;
+ CHAR8 *AsciiUri;
+ UINTN RetryCount;
+ REDFISH_HTTP_CACHE_PRIVATE *Private;
+
+ if ((This == NULL) || (Service == NULL) || (Response == NULL) || IS_EMPTY_STRING (Uri) || IS_EMPTY_STRING (Content)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ DEBUG ((REDFISH_HTTP_CACHE_DEBUG, "%a: Patch URI: %s\n", __func__, Uri));
+
+ Private = REDFISH_HTTP_CACHE_PRIVATE_FROM_THIS (This);
+ AsciiUri = NULL;
+ RetryCount = 0;
+ ZeroMem (Response, sizeof (REDFISH_RESPONSE));
+
+ AsciiUri = StringUnicodeToAscii (Uri);
+ if (AsciiUri == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ //
+ // Patch resource to redfish service.
+ //
+ do {
+ RetryCount += 1;
+ Status = RedfishPatchToUri (
+ Service,
+ AsciiUri,
+ Content,
+ Response
+ );
+ DEBUG ((REDFISH_HTTP_CACHE_DEBUG_REQUEST, "%a: HTTP request: %a :%r\n", __func__, AsciiUri, Status));
+ if (!EFI_ERROR (Status) || (RetryCount >= Private->RetrySetting.MaximumRetryPatch)) {
+ break;
+ }
+
+ //
+ // Retry when BMC is not ready.
+ //
+ if ((Response->StatusCode != NULL)) {
+ DEBUG_CODE (
+ DumpRedfishResponse (NULL, DEBUG_ERROR, Response);
+ );
+
+ if (!RedfishRetryRequired (Response->StatusCode)) {
+ break;
+ }
+
+ //
+ // Release response for next round of request.
+ //
+ This->FreeResponse (This, Response);
+ }
+
+ DEBUG ((DEBUG_WARN, "%a: RedfishPatchToUri failed, retry (%d/%d)\n", __func__, RetryCount, Private->RetrySetting.MaximumRetryPatch));
+ if (Private->RetrySetting.RetryWait > 0) {
+ gBS->Stall (Private->RetrySetting.RetryWait);
+ }
+ } while (TRUE);
+
+ //
+ // Redfish resource is updated. Automatically expire the cached response
+ // so application can directly get resource from Redfish service again.
+ //
+ DEBUG ((REDFISH_HTTP_CACHE_DEBUG, "%a: Resource is updated, expire URI: %s\n", __func__, Uri));
+ RedfishHttpExpireResponse (This, Uri);
+
+ if (EFI_ERROR (Status)) {
+ DEBUG_CODE (
+ DumpRedfishResponse (NULL, DEBUG_ERROR, Response);
+ );
+ //
+ // Report status code for Redfish failure
+ //
+ ReportHttpError (HttpMethodPatch, AsciiUri, Response->StatusCode);
+ DEBUG ((DEBUG_ERROR, "%a: patch %a failed (%d/%d): %r\n", __func__, AsciiUri, RetryCount, Private->RetrySetting.MaximumRetryGet, Status));
+ goto ON_RELEASE;
+ }
+
+ON_RELEASE:
+
+ if (AsciiUri != NULL) {
+ FreePool (AsciiUri);
+ }
+
+ return Status;
+}
+
+/**
+ Perform HTTP PUT to send redfish resource to given resource URI.
+ It's caller's responsibility to free Response by calling FreeResponse ().
+
+ @param[in] This Pointer to EDKII_REDFISH_HTTP_PROTOCOL instance.
+ @param[in] Service Redfish service instance to make query.
+ @param[in] Uri Target resource URI.
+ @param[in] Content Data to put.
+ @param[out] Response HTTP response from redfish service.
+
+ @retval EFI_SUCCESS Resrouce is returned successfully.
+ @retval Others Errors occur.
+
+**/
+EFI_STATUS
+EFIAPI
+RedfishHttpPutResource (
+ IN EDKII_REDFISH_HTTP_PROTOCOL *This,
+ IN REDFISH_SERVICE Service,
+ IN EFI_STRING Uri,
+ IN CHAR8 *Content,
+ OUT REDFISH_RESPONSE *Response
+ )
+{
+ EFI_STATUS Status;
+ CHAR8 *AsciiUri;
+ UINTN RetryCount;
+ REDFISH_HTTP_CACHE_PRIVATE *Private;
+
+ if ((This == NULL) || (Service == NULL) || (Response == NULL) || IS_EMPTY_STRING (Uri) || IS_EMPTY_STRING (Content)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ DEBUG ((REDFISH_HTTP_CACHE_DEBUG, "%a: Put URI: %s\n", __func__, Uri));
+
+ Private = REDFISH_HTTP_CACHE_PRIVATE_FROM_THIS (This);
+ AsciiUri = NULL;
+ RetryCount = 0;
+ ZeroMem (Response, sizeof (REDFISH_RESPONSE));
+
+ AsciiUri = StringUnicodeToAscii (Uri);
+ if (AsciiUri == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ //
+ // Patch resource to redfish service.
+ //
+ do {
+ RetryCount += 1;
+ Status = RedfishPutToUri (
+ Service,
+ AsciiUri,
+ Content,
+ 0,
+ NULL,
+ Response
+ );
+ DEBUG ((REDFISH_HTTP_CACHE_DEBUG_REQUEST, "%a: HTTP request: %a :%r\n", __func__, AsciiUri, Status));
+ if (!EFI_ERROR (Status) || (RetryCount >= Private->RetrySetting.MaximumRetryPut)) {
+ break;
+ }
+
+ //
+ // Retry when BMC is not ready.
+ //
+ if ((Response->StatusCode != NULL)) {
+ DEBUG_CODE (
+ DumpRedfishResponse (NULL, DEBUG_ERROR, Response);
+ );
+
+ if (!RedfishRetryRequired (Response->StatusCode)) {
+ break;
+ }
+
+ //
+ // Release response for next round of request.
+ //
+ This->FreeResponse (This, Response);
+ }
+
+ DEBUG ((DEBUG_WARN, "%a: RedfishPutToUri failed, retry (%d/%d)\n", __func__, RetryCount, Private->RetrySetting.MaximumRetryPut));
+ if (Private->RetrySetting.RetryWait > 0) {
+ gBS->Stall (Private->RetrySetting.RetryWait);
+ }
+ } while (TRUE);
+
+ //
+ // Redfish resource is updated. Automatically expire the cached response
+ // so application can directly get resource from Redfish service again.
+ //
+ DEBUG ((REDFISH_HTTP_CACHE_DEBUG, "%a: Resource is updated, expire URI: %s\n", __func__, Uri));
+ RedfishHttpExpireResponse (This, Uri);
+
+ if (EFI_ERROR (Status)) {
+ DEBUG_CODE (
+ DumpRedfishResponse (NULL, DEBUG_ERROR, Response);
+ );
+ //
+ // Report status code for Redfish failure
+ //
+ ReportHttpError (HttpMethodPut, AsciiUri, Response->StatusCode);
+ DEBUG ((DEBUG_ERROR, "%a: put %a failed (%d/%d): %r\n", __func__, AsciiUri, RetryCount, Private->RetrySetting.MaximumRetryGet, Status));
+ goto ON_RELEASE;
+ }
+
+ON_RELEASE:
+
+ if (AsciiUri != NULL) {
+ FreePool (AsciiUri);
+ }
+
+ return Status;
+}
+
+/**
+ Perform HTTP POST to send redfish resource to given resource URI.
+ It's caller's responsibility to free Response by calling FreeResponse ().
+
+ @param[in] This Pointer to EDKII_REDFISH_HTTP_PROTOCOL instance.
+ @param[in] Service Redfish service instance to make query.
+ @param[in] Uri Target resource URI.
+ @param[in] Content Data to post.
+ @param[out] Response HTTP response from redfish service.
+
+ @retval EFI_SUCCESS Resrouce is returned successfully.
+ @retval Others Errors occur.
+
+**/
+EFI_STATUS
+EFIAPI
+RedfishHttpPostResource (
+ IN EDKII_REDFISH_HTTP_PROTOCOL *This,
+ IN REDFISH_SERVICE Service,
+ IN EFI_STRING Uri,
+ IN CHAR8 *Content,
+ OUT REDFISH_RESPONSE *Response
+ )
+{
+ EFI_STATUS Status;
+ CHAR8 *AsciiUri;
+ UINTN RetryCount;
+ REDFISH_HTTP_CACHE_PRIVATE *Private;
+
+ if ((This == NULL) || (Service == NULL) || (Response == NULL) || IS_EMPTY_STRING (Uri) || IS_EMPTY_STRING (Content)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ DEBUG ((REDFISH_HTTP_CACHE_DEBUG, "%a: Post URI: %s\n", __func__, Uri));
+
+ Private = REDFISH_HTTP_CACHE_PRIVATE_FROM_THIS (This);
+ AsciiUri = NULL;
+ RetryCount = 0;
+ ZeroMem (Response, sizeof (REDFISH_RESPONSE));
+
+ AsciiUri = StringUnicodeToAscii (Uri);
+ if (AsciiUri == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ //
+ // Patch resource to redfish service.
+ //
+ do {
+ RetryCount += 1;
+ Status = RedfishPostToUri (
+ Service,
+ AsciiUri,
+ Content,
+ 0,
+ NULL,
+ Response
+ );
+ DEBUG ((REDFISH_HTTP_CACHE_DEBUG_REQUEST, "%a: HTTP request: %a :%r\n", __func__, AsciiUri, Status));
+ if (!EFI_ERROR (Status) || (RetryCount >= Private->RetrySetting.MaximumRetryPut)) {
+ break;
+ }
+
+ //
+ // Retry when BMC is not ready.
+ //
+ if ((Response->StatusCode != NULL)) {
+ DEBUG_CODE (
+ DumpRedfishResponse (NULL, DEBUG_ERROR, Response);
+ );
+
+ if (!RedfishRetryRequired (Response->StatusCode)) {
+ break;
+ }
+
+ //
+ // Release response for next round of request.
+ //
+ This->FreeResponse (This, Response);
+ }
+
+ DEBUG ((DEBUG_WARN, "%a: RedfishPostToUri failed, retry (%d/%d)\n", __func__, RetryCount, Private->RetrySetting.MaximumRetryPut));
+ if (Private->RetrySetting.RetryWait > 0) {
+ gBS->Stall (Private->RetrySetting.RetryWait);
+ }
+ } while (TRUE);
+
+ //
+ // Redfish resource is updated. Automatically expire the cached response
+ // so application can directly get resource from Redfish service again.
+ //
+ DEBUG ((REDFISH_HTTP_CACHE_DEBUG, "%a: Resource is updated, expire URI: %s\n", __func__, Uri));
+ RedfishHttpExpireResponse (This, Uri);
+
+ if (EFI_ERROR (Status)) {
+ DEBUG_CODE (
+ DumpRedfishResponse (NULL, DEBUG_ERROR, Response);
+ );
+ //
+ // Report status code for Redfish failure
+ //
+ ReportHttpError (HttpMethodPost, AsciiUri, Response->StatusCode);
+ DEBUG ((DEBUG_ERROR, "%a: post %a failed (%d/%d): %r\n", __func__, AsciiUri, RetryCount, Private->RetrySetting.MaximumRetryGet, Status));
+ goto ON_RELEASE;
+ }
+
+ON_RELEASE:
+
+ if (AsciiUri != NULL) {
+ FreePool (AsciiUri);
+ }
+
+ return Status;
+}
+
+/**
+ Perform HTTP DELETE to delete redfish resource on given resource URI.
+ It's caller's responsibility to free Response by calling FreeResponse ().
+
+ @param[in] This Pointer to EDKII_REDFISH_HTTP_PROTOCOL instance.
+ @param[in] Service Redfish service instance to make query.
+ @param[in] Uri Target resource URI.
+ @param[out] Response HTTP response from redfish service.
+
+ @retval EFI_SUCCESS Resrouce is returned successfully.
+ @retval Others Errors occur.
+
+**/
+EFI_STATUS
+EFIAPI
+RedfishHttpDeleteResource (
+ IN EDKII_REDFISH_HTTP_PROTOCOL *This,
+ IN REDFISH_SERVICE Service,
+ IN EFI_STRING Uri,
+ OUT REDFISH_RESPONSE *Response
+ )
+{
+ EFI_STATUS Status;
+ CHAR8 *AsciiUri;
+ UINTN RetryCount;
+ REDFISH_HTTP_CACHE_PRIVATE *Private;
+
+ if ((This == NULL) || (Service == NULL) || (Response == NULL) || IS_EMPTY_STRING (Uri)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ DEBUG ((REDFISH_HTTP_CACHE_DEBUG, "%a: Delete URI: %s\n", __func__, Uri));
+
+ Private = REDFISH_HTTP_CACHE_PRIVATE_FROM_THIS (This);
+ AsciiUri = NULL;
+ RetryCount = 0;
+ ZeroMem (Response, sizeof (REDFISH_RESPONSE));
+
+ AsciiUri = StringUnicodeToAscii (Uri);
+ if (AsciiUri == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ //
+ // Patch resource to redfish service.
+ //
+ do {
+ RetryCount += 1;
+ Status = RedfishDeleteByUri (
+ Service,
+ AsciiUri,
+ Response
+ );
+ DEBUG ((REDFISH_HTTP_CACHE_DEBUG_REQUEST, "%a: HTTP request: %a :%r\n", __func__, AsciiUri, Status));
+ if (!EFI_ERROR (Status) || (RetryCount >= Private->RetrySetting.MaximumRetryDelete)) {
+ break;
+ }
+
+ //
+ // Retry when BMC is not ready.
+ //
+ if ((Response->StatusCode != NULL)) {
+ DEBUG_CODE (
+ DumpRedfishResponse (NULL, DEBUG_ERROR, Response);
+ );
+
+ if (!RedfishRetryRequired (Response->StatusCode)) {
+ break;
+ }
+
+ //
+ // Release response for next round of request.
+ //
+ This->FreeResponse (This, Response);
+ }
+
+ DEBUG ((DEBUG_WARN, "%a: RedfishDeleteByUri failed, retry (%d/%d)\n", __func__, RetryCount, Private->RetrySetting.MaximumRetryDelete));
+ if (Private->RetrySetting.RetryWait > 0) {
+ gBS->Stall (Private->RetrySetting.RetryWait);
+ }
+ } while (TRUE);
+
+ //
+ // Redfish resource is updated. Automatically expire the cached response
+ // so application can directly get resource from Redfish service again.
+ //
+ DEBUG ((REDFISH_HTTP_CACHE_DEBUG, "%a: Resource is updated, expire URI: %s\n", __func__, Uri));
+ RedfishHttpExpireResponse (This, Uri);
+
+ if (EFI_ERROR (Status)) {
+ DEBUG_CODE (
+ DumpRedfishResponse (NULL, DEBUG_ERROR, Response);
+ );
+ //
+ // Report status code for Redfish failure
+ //
+ ReportHttpError (HttpMethodDelete, AsciiUri, Response->StatusCode);
+ DEBUG ((DEBUG_ERROR, "%a: delete %a failed (%d/%d): %r\n", __func__, AsciiUri, RetryCount, Private->RetrySetting.MaximumRetryGet, Status));
+ goto ON_RELEASE;
+ }
+
+ON_RELEASE:
+
+ if (AsciiUri != NULL) {
+ FreePool (AsciiUri);
+ }
+
+ return Status;
+}
+
+EDKII_REDFISH_HTTP_PROTOCOL mRedfishHttpProtocol = {
+ EDKII_REDFISH_HTTP_PROTOCOL_REVISION,
+ RedfishHttpGetResource,
+ RedfishHttpPatchResource,
+ RedfishHttpPutResource,
+ RedfishHttpPostResource,
+ RedfishHttpDeleteResource,
+ RedfishHttpFreeResponse,
+ RedfishHttpExpireResponse
+};
+
+/**
+ Unloads an image.
+
+ @param[in] 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
+RedfishHttpDriverUnload (
+ IN EFI_HANDLE ImageHandle
+ )
+{
+ if (mRedfishHttpCachePrivate == NULL) {
+ return EFI_SUCCESS;
+ }
+
+ if (!IsListEmpty (&mRedfishHttpCachePrivate->CacheList.Head)) {
+ ReleaseCacheList (&mRedfishHttpCachePrivate->CacheList);
+ }
+
+ gBS->UninstallMultipleProtocolInterfaces (
+ ImageHandle,
+ &gEdkIIRedfishHttpProtocolGuid,
+ &mRedfishHttpCachePrivate->Protocol,
+ NULL
+ );
+
+ FreePool (mRedfishHttpCachePrivate);
+ mRedfishHttpCachePrivate = NULL;
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Main entry for this driver.
+
+ @param[in] ImageHandle Image handle this driver.
+ @param[in] SystemTable Pointer to SystemTable.
+
+ @retval EFI_SUCCESS This function always complete successfully.
+
+**/
+EFI_STATUS
+EFIAPI
+RedfishHttpEntryPoint (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+
+ if (mRedfishHttpCachePrivate != NULL) {
+ return EFI_ALREADY_STARTED;
+ }
+
+ mRedfishHttpCachePrivate = AllocateZeroPool (sizeof (REDFISH_HTTP_CACHE_PRIVATE));
+ if (mRedfishHttpCachePrivate == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ //
+ // Initial cache list and protocol instance.
+ //
+ mRedfishHttpCachePrivate->ImageHandle = ImageHandle;
+ CopyMem (&mRedfishHttpCachePrivate->Protocol, &mRedfishHttpProtocol, sizeof (EDKII_REDFISH_HTTP_PROTOCOL));
+ mRedfishHttpCachePrivate->CacheList.Capacity = REDFISH_HTTP_CACHE_LIST_SIZE;
+ mRedfishHttpCachePrivate->CacheList.Count = 0x00;
+ mRedfishHttpCachePrivate->CacheDisabled = PcdGetBool (PcdHttpCacheDisabled);
+ InitializeListHead (&mRedfishHttpCachePrivate->CacheList.Head);
+
+ //
+ // Get retry settings
+ //
+ mRedfishHttpCachePrivate->RetrySetting.MaximumRetryGet = PcdGet16 (PcdHttpGetRetry);
+ mRedfishHttpCachePrivate->RetrySetting.MaximumRetryPut = PcdGet16 (PcdHttpPutRetry);
+ mRedfishHttpCachePrivate->RetrySetting.MaximumRetryPatch = PcdGet16 (PcdHttpPatchRetry);
+ mRedfishHttpCachePrivate->RetrySetting.MaximumRetryPost = PcdGet16 (PcdHttpPostRetry);
+ mRedfishHttpCachePrivate->RetrySetting.MaximumRetryDelete = PcdGet16 (PcdHttpDeleteRetry);
+ mRedfishHttpCachePrivate->RetrySetting.RetryWait = PcdGet16 (PcdHttpRetryWaitInSecond) * 1000000U;
+
+ //
+ // Install the gEdkIIRedfishHttpProtocolGuid onto Handle.
+ //
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &mRedfishHttpCachePrivate->ImageHandle,
+ &gEdkIIRedfishHttpProtocolGuid,
+ &mRedfishHttpCachePrivate->Protocol,
+ NULL
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a: cannot install Redfish http protocol: %r\n", __func__, Status));
+ RedfishHttpDriverUnload (ImageHandle);
+ return Status;
+ }
+
+ return EFI_SUCCESS;
+}
diff --git a/RedfishClientPkg/RedfishHttpDxe/RedfishHttpDxe.h b/RedfishClientPkg/RedfishHttpDxe/RedfishHttpDxe.h
new file mode 100644
index 000000000..6a746aebe
--- /dev/null
+++ b/RedfishClientPkg/RedfishHttpDxe/RedfishHttpDxe.h
@@ -0,0 +1,38 @@
+/** @file
+ Definitions of RedfishHttpDxe
+
+ Copyright (c) 2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef EDKII_REDFISH_HTTP_DXE_H_
+#define EDKII_REDFISH_HTTP_DXE_H_
+
+#include
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+
+#define REDFISH_HTTP_CACHE_LIST_SIZE 0x80
+#define REDFISH_ERROR_MSG_MAX 128
+#define REDFISH_HTTP_ERROR_REPORT "Redfish HTTP %a failure(0x%x): %a"
+#define REDFISH_HTTP_CACHE_DEBUG DEBUG_MANAGEABILITY
+#define REDFISH_HTTP_CACHE_DEBUG_DUMP DEBUG_MANAGEABILITY
+#define REDFISH_HTTP_CACHE_DEBUG_REQUEST DEBUG_MANAGEABILITY
+
+#endif
diff --git a/RedfishClientPkg/RedfishHttpDxe/RedfishHttpDxe.inf b/RedfishClientPkg/RedfishHttpDxe/RedfishHttpDxe.inf
new file mode 100644
index 000000000..2221b64e0
--- /dev/null
+++ b/RedfishClientPkg/RedfishHttpDxe/RedfishHttpDxe.inf
@@ -0,0 +1,64 @@
+## @file
+# RedfishHttpDxe is the DXE driver which provides
+# EdkIIRedfishHttpProtocol to EDK2 Redfish Feature
+# drivers for HTTP operation.
+#
+# Copyright (c) 2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x0001000b
+ BASE_NAME = RedfishHttpDxe
+ FILE_GUID = 9B9CB3B9-AC38-49A9-B62E-C42B7B464835
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ ENTRY_POINT = RedfishHttpEntryPoint
+ UNLOAD_IMAGE = RedfishHttpDriverUnload
+
+#
+# VALID_ARCHITECTURES = IA32 X64 ARM AARCH64 RISCV64
+#
+
+[Sources]
+ RedfishHttpData.c
+ RedfishHttpData.h
+ RedfishHttpDxe.c
+ RedfishHttpDxe.h
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ NetworkPkg/NetworkPkg.dec
+ RedfishPkg/RedfishPkg.dec
+ RedfishClientPkg/RedfishClientPkg.dec
+
+[LibraryClasses]
+ BaseLib
+ BaseMemoryLib
+ DebugLib
+ MemoryAllocationLib
+ PrintLib
+ RedfishLib
+ RedfishDebugLib
+ ReportStatusCodeLib
+ UefiBootServicesTableLib
+ UefiDriverEntryPoint
+ UefiLib
+
+[Protocols]
+ gEdkIIRedfishHttpProtocolGuid ## PRODUCED
+
+[Pcd]
+ gEfiRedfishClientPkgTokenSpaceGuid.PcdHttpGetRetry
+ gEfiRedfishClientPkgTokenSpaceGuid.PcdHttpPutRetry
+ gEfiRedfishClientPkgTokenSpaceGuid.PcdHttpPatchRetry
+ gEfiRedfishClientPkgTokenSpaceGuid.PcdHttpPostRetry
+ gEfiRedfishClientPkgTokenSpaceGuid.PcdHttpDeleteRetry
+ gEfiRedfishClientPkgTokenSpaceGuid.PcdHttpRetryWaitInSecond
+ gEfiRedfishClientPkgTokenSpaceGuid.PcdHttpCacheDisabled
+
+[Depex]
+ TRUE