mirror of https://github.com/acidanthera/audk.git
1034 lines
34 KiB
C
1034 lines
34 KiB
C
/** @file
|
|
Provides a set of utility APIs that allow to create/read/update/delete
|
|
(CRUD) Redfish resources and provide basic query.
|
|
|
|
Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
|
|
(C) Copyright 2021 Hewlett Packard Enterprise Development LP<BR>
|
|
|
|
SPDX-License-Identifier: BSD-2-Clause-Patent
|
|
|
|
**/
|
|
|
|
#include "RedfishMisc.h"
|
|
|
|
/**
|
|
This function uses REST EX protocol provided in RedfishConfigServiceInfo.
|
|
The service enumerator will also handle the authentication flow automatically
|
|
if HTTP basic auth or Redfish session login is configured to use.
|
|
|
|
Callers are responsible for freeing the returned service by RedfishCleanupService().
|
|
|
|
@param[in] RedfishConfigServiceInfo Redfish service information the EFI Redfish
|
|
feature driver communicates with.
|
|
|
|
@return New created Redfish Service, or NULL if error happens.
|
|
|
|
**/
|
|
REDFISH_SERVICE
|
|
EFIAPI
|
|
RedfishCreateService (
|
|
IN REDFISH_CONFIG_SERVICE_INFORMATION *RedfishConfigServiceInfo
|
|
)
|
|
{
|
|
REDFISH_SERVICE RedfishService;
|
|
EDKII_REDFISH_AUTH_METHOD AuthMethod;
|
|
CHAR8 *UserId;
|
|
CHAR8 *Password;
|
|
EFI_STATUS Status;
|
|
|
|
RedfishService = NULL;
|
|
UserId = NULL;
|
|
Password = NULL;
|
|
|
|
//
|
|
// Check Input Parameters.
|
|
//
|
|
if (RedfishConfigServiceInfo == NULL) {
|
|
return NULL;
|
|
}
|
|
|
|
//
|
|
// Get Authentication Configuration.
|
|
//
|
|
Status = RedfishGetAuthInfo (&AuthMethod, &UserId, &Password);
|
|
if (EFI_ERROR (Status)) {
|
|
goto ON_EXIT;
|
|
}
|
|
|
|
//
|
|
// Create a redfish service node based on Redfish network host interface.
|
|
//
|
|
RedfishService = RedfishCreateLibredfishService (
|
|
RedfishConfigServiceInfo,
|
|
AuthMethod,
|
|
UserId,
|
|
Password
|
|
);
|
|
|
|
ON_EXIT:
|
|
if (UserId != NULL) {
|
|
FreePool (UserId);
|
|
}
|
|
|
|
if (Password != NULL) {
|
|
FreePool (Password);
|
|
}
|
|
|
|
return RedfishService;
|
|
}
|
|
|
|
/**
|
|
Free the Service and all its related resources.
|
|
|
|
@param[in] RedfishService The Service to access the Redfish resources.
|
|
|
|
**/
|
|
VOID
|
|
EFIAPI
|
|
RedfishCleanupService (
|
|
IN REDFISH_SERVICE RedfishService
|
|
)
|
|
{
|
|
if (RedfishService == NULL) {
|
|
return;
|
|
}
|
|
|
|
cleanupServiceEnumerator (RedfishService);
|
|
}
|
|
|
|
/**
|
|
Create REDFISH_PAYLOAD instance in local with JSON represented resource value and
|
|
the Redfish Service.
|
|
|
|
The returned REDFISH_PAYLOAD can be used to create or update Redfish resource in
|
|
server side.
|
|
|
|
Callers are responsible for freeing the returned payload by RedfishCleanupPayload().
|
|
|
|
@param[in] Value JSON Value of the redfish resource.
|
|
@param[in] RedfishService The Service to access the Redfish resources.
|
|
|
|
@return REDFISH_PAYLOAD instance of the resource, or NULL if error happens.
|
|
|
|
**/
|
|
REDFISH_PAYLOAD
|
|
EFIAPI
|
|
RedfishCreatePayload (
|
|
IN EDKII_JSON_VALUE Value,
|
|
IN REDFISH_SERVICE RedfishService
|
|
)
|
|
{
|
|
EDKII_JSON_VALUE CopyValue;
|
|
|
|
CopyValue = JsonValueClone (Value);
|
|
return createRedfishPayload (CopyValue, RedfishService);
|
|
}
|
|
|
|
/**
|
|
Free the RedfishPayload and all its related resources.
|
|
|
|
@param[in] Payload Payload to be freed.
|
|
|
|
**/
|
|
VOID
|
|
EFIAPI
|
|
RedfishCleanupPayload (
|
|
IN REDFISH_PAYLOAD Payload
|
|
)
|
|
{
|
|
if (Payload == NULL) {
|
|
return;
|
|
}
|
|
|
|
cleanupPayload ((redfishPayload *)Payload);
|
|
}
|
|
|
|
/**
|
|
This function returns the decoded JSON value of a REDFISH_PAYLOAD.
|
|
|
|
Caller doesn't need to free the returned JSON value because it will be released
|
|
in corresponding RedfishCleanupPayload() function.
|
|
|
|
@param[in] Payload A REDFISH_PAYLOAD instance.
|
|
|
|
@return Decoded JSON value of the payload.
|
|
|
|
**/
|
|
EDKII_JSON_VALUE
|
|
EFIAPI
|
|
RedfishJsonInPayload (
|
|
IN REDFISH_PAYLOAD Payload
|
|
)
|
|
{
|
|
if (Payload == NULL) {
|
|
return NULL;
|
|
}
|
|
|
|
return ((redfishPayload *)Payload)->json;
|
|
}
|
|
|
|
/**
|
|
Fill the input RedPath string with system UUID from SMBIOS table or use the customized
|
|
ID if FromSmbios == FALSE.
|
|
|
|
This is a helper function to build a RedPath string which can be used to address
|
|
a Redfish resource for this computer system. The input PathString must have a Systems
|
|
note in format of "Systems[UUID=%g]" or "Systems[UUID~%g]" to fill the UUID value.
|
|
|
|
Example:
|
|
Use "/v1/Systems[UUID=%g]/Bios" to build a RedPath to address the "Bios" resource
|
|
for this computer system.
|
|
|
|
@param[in] RedPath RedPath format to be build.
|
|
@param[in] FromSmbios Get system UUID from SMBIOS as computer system instance ID.
|
|
@param[in] IdString The computer system instance ID.
|
|
|
|
@return Full RedPath with system UUID inside, or NULL if error happens.
|
|
|
|
**/
|
|
CHAR8 *
|
|
EFIAPI
|
|
RedfishBuildPathWithSystemUuid (
|
|
IN CONST CHAR8 *RedPath,
|
|
IN BOOLEAN FromSmbios,
|
|
IN CHAR8 *IdString OPTIONAL
|
|
)
|
|
{
|
|
UINTN BufSize;
|
|
CHAR8 *RetRedPath;
|
|
EFI_GUID SystemUuid;
|
|
EFI_STATUS Status;
|
|
|
|
if (RedPath == NULL) {
|
|
return NULL;
|
|
}
|
|
|
|
//
|
|
// Find system UUID from SMBIOS table.
|
|
//
|
|
if (FromSmbios) {
|
|
Status = NetLibGetSystemGuid (&SystemUuid);
|
|
if (EFI_ERROR (Status)) {
|
|
return NULL;
|
|
}
|
|
|
|
// AsciiStrLen ("xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx") = 36
|
|
BufSize = AsciiStrSize (RedPath) + AsciiStrLen ("XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX");
|
|
} else {
|
|
BufSize = AsciiStrSize (RedPath) + AsciiStrLen (IdString);
|
|
}
|
|
|
|
RetRedPath = AllocateZeroPool (BufSize);
|
|
if (RetRedPath == NULL) {
|
|
return NULL;
|
|
}
|
|
|
|
if (FromSmbios) {
|
|
AsciiSPrint (RetRedPath, BufSize, RedPath, &SystemUuid);
|
|
} else {
|
|
AsciiSPrint (RetRedPath, BufSize, RedPath, IdString);
|
|
}
|
|
|
|
return RetRedPath;
|
|
}
|
|
|
|
/**
|
|
Get a redfish response addressed by a RedPath string, including HTTP StatusCode, Headers
|
|
and Payload which record any HTTP response messages.
|
|
|
|
Callers are responsible for freeing the HTTP StatusCode, Headers and Payload returned in
|
|
redfish response data.
|
|
|
|
@param[in] RedfishService The Service to access the Redfish resources.
|
|
@param[in] RedPath RedPath string to address a resource, must start
|
|
from the root node.
|
|
@param[out] RedResponse Pointer to the Redfish response data.
|
|
|
|
@retval EFI_SUCCESS The opeartion is successful, indicates the HTTP StatusCode is not
|
|
NULL and the value is 2XX. The corresponding redfish resource has
|
|
been returned in Payload within RedResponse.
|
|
@retval EFI_INVALID_PARAMETER RedfishService, RedPath, or RedResponse is NULL.
|
|
@retval EFI_DEVICE_ERROR An unexpected system or network error occurred. Callers can get
|
|
more error info from returned HTTP StatusCode, Headers and Payload
|
|
within RedResponse:
|
|
1. If the returned Payload is NULL, indicates any error happen.
|
|
2. If the returned StatusCode is NULL, indicates any error happen.
|
|
3. If the returned StatusCode is not 2XX, indicates any error happen.
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
RedfishGetByService (
|
|
IN REDFISH_SERVICE RedfishService,
|
|
IN CONST CHAR8 *RedPath,
|
|
OUT REDFISH_RESPONSE *RedResponse
|
|
)
|
|
{
|
|
if ((RedfishService == NULL) || (RedPath == NULL) || (RedResponse == NULL)) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
ZeroMem (RedResponse, sizeof (REDFISH_RESPONSE));
|
|
|
|
RedResponse->Payload = (REDFISH_PAYLOAD)getPayloadByPath (RedfishService, RedPath, &(RedResponse->StatusCode));
|
|
|
|
//
|
|
// 1. If the returned Payload is NULL, indicates any error happen.
|
|
// 2. If the returned StatusCode is NULL, indicates any error happen.
|
|
//
|
|
if ((RedResponse->Payload == NULL) || (RedResponse->StatusCode == NULL)) {
|
|
return EFI_DEVICE_ERROR;
|
|
}
|
|
|
|
//
|
|
// 3. If the returned StatusCode is not 2XX, indicates any error happen.
|
|
// NOTE: If there is any error message returned from server, it will be returned in
|
|
// Payload within RedResponse.
|
|
//
|
|
if ((*(RedResponse->StatusCode) < HTTP_STATUS_200_OK) || \
|
|
(*(RedResponse->StatusCode) > HTTP_STATUS_206_PARTIAL_CONTENT))
|
|
{
|
|
return EFI_DEVICE_ERROR;
|
|
}
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
Get a redfish response addressed by URI, including HTTP StatusCode, Headers
|
|
and Payload which record any HTTP response messages.
|
|
|
|
Callers are responsible for freeing the HTTP StatusCode, Headers and Payload returned in
|
|
redfish response data.
|
|
|
|
@param[in] RedfishService The Service to access the URI resources.
|
|
@param[in] Uri String to address a resource.
|
|
@param[out] RedResponse Pointer to the Redfish response data.
|
|
|
|
@retval EFI_SUCCESS The opeartion is successful, indicates the HTTP StatusCode is not
|
|
NULL and the value is 2XX. The corresponding redfish resource has
|
|
been returned in Payload within RedResponse.
|
|
@retval EFI_INVALID_PARAMETER RedfishService, RedPath, or RedResponse is NULL.
|
|
@retval EFI_DEVICE_ERROR An unexpected system or network error occurred. Callers can get
|
|
more error info from returned HTTP StatusCode, Headers and Payload
|
|
within RedResponse:
|
|
1. If the returned Payload is NULL, indicates any error happen.
|
|
2. If the returned StatusCode is NULL, indicates any error happen.
|
|
3. If the returned StatusCode is not 2XX, indicates any error happen.
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
RedfishGetByUri (
|
|
IN REDFISH_SERVICE RedfishService,
|
|
IN CONST CHAR8 *Uri,
|
|
OUT REDFISH_RESPONSE *RedResponse
|
|
)
|
|
{
|
|
EDKII_JSON_VALUE JsonValue;
|
|
|
|
if ((RedfishService == NULL) || (Uri == NULL) || (RedResponse == NULL)) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
ZeroMem (RedResponse, sizeof (REDFISH_RESPONSE));
|
|
|
|
JsonValue = getUriFromService (RedfishService, Uri, &RedResponse->StatusCode);
|
|
RedResponse->Payload = createRedfishPayload (JsonValue, RedfishService);
|
|
|
|
//
|
|
// 1. If the returned Payload is NULL, indicates any error happen.
|
|
// 2. If the returned StatusCode is NULL, indicates any error happen.
|
|
//
|
|
if ((RedResponse->Payload == NULL) || (RedResponse->StatusCode == NULL)) {
|
|
return EFI_DEVICE_ERROR;
|
|
}
|
|
|
|
//
|
|
// 3. If the returned StatusCode is not 2XX, indicates any error happen.
|
|
// NOTE: If there is any error message returned from server, it will be returned in
|
|
// Payload within RedResponse.
|
|
//
|
|
if ((*(RedResponse->StatusCode) < HTTP_STATUS_200_OK) || \
|
|
(*(RedResponse->StatusCode) > HTTP_STATUS_206_PARTIAL_CONTENT))
|
|
{
|
|
return EFI_DEVICE_ERROR;
|
|
}
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
Get a redfish response addressed by the input Payload and relative RedPath string,
|
|
including HTTP StatusCode, Headers and Payload which record any HTTP response messages.
|
|
|
|
Callers are responsible for freeing the HTTP StatusCode, Headers and Payload returned in
|
|
redfish response data.
|
|
|
|
@param[in] Payload A existing REDFISH_PAYLOAD instance.
|
|
@param[in] RedPath Relative RedPath string to address a resource inside Payload.
|
|
@param[out] RedResponse Pointer to the Redfish response data.
|
|
|
|
@retval EFI_SUCCESS The opeartion is successful:
|
|
1. The HTTP StatusCode is NULL and the returned Payload in
|
|
RedResponse is not NULL, indicates the Redfish resource has
|
|
been parsed from the input payload directly.
|
|
2. The HTTP StatusCode is not NULL and the value is 2XX,
|
|
indicates the corresponding redfish resource has been returned
|
|
in Payload within RedResponse.
|
|
@retval EFI_INVALID_PARAMETER Payload, RedPath, or RedResponse is NULL.
|
|
@retval EFI_DEVICE_ERROR An unexpected system or network error occurred. Callers can get
|
|
more error info from returned HTTP StatusCode, Headers and Payload
|
|
within RedResponse:
|
|
1. If the returned Payload is NULL, indicates any error happen.
|
|
2. If StatusCode is not NULL and the returned value of StatusCode
|
|
is not 2XX, indicates any error happen.
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
RedfishGetByPayload (
|
|
IN REDFISH_PAYLOAD Payload,
|
|
IN CONST CHAR8 *RedPath,
|
|
OUT REDFISH_RESPONSE *RedResponse
|
|
)
|
|
{
|
|
if ((Payload == NULL) || (RedPath == NULL) || (RedResponse == NULL)) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
ZeroMem (RedResponse, sizeof (REDFISH_RESPONSE));
|
|
|
|
RedResponse->Payload = (REDFISH_PAYLOAD)getPayloadForPathString (Payload, RedPath, &(RedResponse->StatusCode));
|
|
|
|
//
|
|
// 1. If the returned Payload is NULL, indicates any error happen.
|
|
//
|
|
if (RedResponse->Payload == NULL) {
|
|
return EFI_DEVICE_ERROR;
|
|
}
|
|
|
|
//
|
|
// 2. If StatusCode is not NULL and the returned value of StatusCode is not 2XX, indicates any
|
|
// error happen.
|
|
// NOTE: If there is any error message returned from server, it will be returned in
|
|
// Payload within RedResponse.
|
|
//
|
|
if ((RedResponse->StatusCode != NULL) && \
|
|
((*(RedResponse->StatusCode) < HTTP_STATUS_200_OK) || \
|
|
(*(RedResponse->StatusCode) > HTTP_STATUS_206_PARTIAL_CONTENT)
|
|
))
|
|
{
|
|
return EFI_DEVICE_ERROR;
|
|
}
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
Use HTTP PATCH to perform updates on pre-existing Redfish resource.
|
|
|
|
This function uses the RedfishService to patch a Redfish resource addressed by
|
|
Uri (only the relative path is required). Changes to one or more properties within
|
|
the target resource are represented in the input Content, properties not specified
|
|
in Content won't be changed by this request. The corresponding redfish response will
|
|
returned, including HTTP StatusCode, Headers and Payload which record any HTTP response
|
|
messages.
|
|
|
|
Callers are responsible for freeing the HTTP StatusCode, Headers and Payload returned in
|
|
redfish response data.
|
|
|
|
@param[in] RedfishService The Service to access the Redfish resources.
|
|
@param[in] Uri Relative path to address the resource.
|
|
@param[in] Content JSON represented properties to be update.
|
|
@param[out] RedResponse Pointer to the Redfish response data.
|
|
|
|
@retval EFI_SUCCESS The opeartion is successful, indicates the HTTP StatusCode is not
|
|
NULL and the value is 2XX. The Redfish resource will be returned
|
|
in Payload within RedResponse if server send it back in the HTTP
|
|
response message body.
|
|
@retval EFI_INVALID_PARAMETER RedfishService, Uri, Content, or RedResponse is NULL.
|
|
@retval EFI_DEVICE_ERROR An unexpected system or network error occurred. Callers can get
|
|
more error info from returned HTTP StatusCode, Headers and Payload
|
|
within RedResponse:
|
|
1. If the returned StatusCode is NULL, indicates any error happen.
|
|
2. If the returned StatusCode is not NULL and the value is not 2XX,
|
|
indicates any error happen.
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
RedfishPatchToUri (
|
|
IN REDFISH_SERVICE RedfishService,
|
|
IN CONST CHAR8 *Uri,
|
|
IN CONST CHAR8 *Content,
|
|
OUT REDFISH_RESPONSE *RedResponse
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
EDKII_JSON_VALUE JsonValue;
|
|
|
|
Status = EFI_SUCCESS;
|
|
JsonValue = NULL;
|
|
|
|
if ((RedfishService == NULL) || (Uri == NULL) || (Content == NULL) || (RedResponse == NULL)) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
ZeroMem (RedResponse, sizeof (REDFISH_RESPONSE));
|
|
|
|
JsonValue = (EDKII_JSON_VALUE)patchUriFromService (
|
|
RedfishService,
|
|
Uri,
|
|
Content,
|
|
&(RedResponse->StatusCode)
|
|
);
|
|
|
|
//
|
|
// 1. If the returned StatusCode is NULL, indicates any error happen.
|
|
//
|
|
if (RedResponse->StatusCode == NULL) {
|
|
Status = EFI_DEVICE_ERROR;
|
|
goto ON_EXIT;
|
|
}
|
|
|
|
//
|
|
// 2. If the returned StatusCode is not NULL and the value is not 2XX, indicates any error happen.
|
|
// NOTE: If there is any error message returned from server, it will be returned in
|
|
// Payload within RedResponse.
|
|
//
|
|
if ((*(RedResponse->StatusCode) < HTTP_STATUS_200_OK) || \
|
|
(*(RedResponse->StatusCode) > HTTP_STATUS_206_PARTIAL_CONTENT))
|
|
{
|
|
Status = EFI_DEVICE_ERROR;
|
|
}
|
|
|
|
ON_EXIT:
|
|
if (JsonValue != NULL) {
|
|
RedResponse->Payload = createRedfishPayload (JsonValue, RedfishService);
|
|
if (RedResponse->Payload == NULL) {
|
|
//
|
|
// Ignore the error when create RedfishPayload, just free the JsonValue since it's not what
|
|
// we care about if the returned StatusCode is 2XX.
|
|
//
|
|
JsonValueFree (JsonValue);
|
|
}
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
|
|
/**
|
|
Use HTTP PATCH to perform updates on target payload. Patch to odata.id in Payload directly.
|
|
|
|
This function uses the Payload to patch the Target. Changes to one or more properties
|
|
within the target resource are represented in the input Payload, properties not specified
|
|
in Payload won't be changed by this request. The corresponding redfish response will
|
|
returned, including HTTP StatusCode, Headers and Payload which record any HTTP response
|
|
messages.
|
|
|
|
Callers are responsible for freeing the HTTP StatusCode, Headers and Payload returned in
|
|
redfish response data.
|
|
|
|
@param[in] Target The target payload to be updated.
|
|
@param[in] Payload Palyoad with properties to be changed.
|
|
@param[out] RedResponse Pointer to the Redfish response data.
|
|
|
|
@retval EFI_SUCCESS The opeartion is successful, indicates the HTTP StatusCode is not
|
|
NULL and the value is 2XX. The Redfish resource will be returned
|
|
in Payload within RedResponse if server send it back in the HTTP
|
|
response message body.
|
|
@retval EFI_INVALID_PARAMETER Target, Payload, or RedResponse is NULL.
|
|
@retval EFI_DEVICE_ERROR An unexpected system or network error occurred. Callers can get
|
|
more error info from returned HTTP StatusCode, Headers and Payload
|
|
within RedResponse:
|
|
1. If the returned StatusCode is NULL, indicates any error happen.
|
|
2. If the returned StatusCode is not NULL and the value is not 2XX,
|
|
indicates any error happen.
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
RedfishPatchToPayload (
|
|
IN REDFISH_PAYLOAD Target,
|
|
IN REDFISH_PAYLOAD Payload,
|
|
OUT REDFISH_RESPONSE *RedResponse
|
|
)
|
|
{
|
|
if ((Target == NULL) || (Payload == NULL) || (RedResponse == NULL)) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
ZeroMem (RedResponse, sizeof (REDFISH_RESPONSE));
|
|
|
|
RedResponse->Payload = (REDFISH_PAYLOAD)patchPayload (
|
|
Target,
|
|
Payload,
|
|
&(RedResponse->StatusCode)
|
|
);
|
|
|
|
//
|
|
// 1. If the returned StatusCode is NULL, indicates any error happen.
|
|
//
|
|
if (RedResponse->StatusCode == NULL) {
|
|
return EFI_DEVICE_ERROR;
|
|
}
|
|
|
|
//
|
|
// 2. If the returned StatusCode is not NULL and the value is not 2XX, indicates any error happen.
|
|
// NOTE: If there is any error message returned from server, it will be returned in
|
|
// Payload within RedResponse.
|
|
//
|
|
if ((*(RedResponse->StatusCode) < HTTP_STATUS_200_OK) || \
|
|
(*(RedResponse->StatusCode) > HTTP_STATUS_206_PARTIAL_CONTENT))
|
|
{
|
|
return EFI_DEVICE_ERROR;
|
|
}
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
Use HTTP POST to create a new resource in target payload.
|
|
|
|
The POST request should be submitted to the Resource Collection in which the new resource
|
|
is to belong. The Resource Collection is addressed by Target payload. The Redfish may
|
|
ignore any service controlled properties. The corresponding redfish response will returned,
|
|
including HTTP StatusCode, Headers and Payload which record any HTTP response messages.
|
|
|
|
Callers are responsible for freeing the HTTP StatusCode, Headers and Payload returned in
|
|
redfish response data.
|
|
|
|
@param[in] Target Target payload of the Resource Collection.
|
|
@param[in] Payload The new resource to be created.
|
|
@param[out] RedResponse Pointer to the Redfish response data.
|
|
|
|
@retval EFI_SUCCESS The opeartion is successful, indicates the HTTP StatusCode is not
|
|
NULL and the value is 2XX. The Redfish resource will be returned
|
|
in Payload within RedResponse if server send it back in the HTTP
|
|
response message body.
|
|
@retval EFI_INVALID_PARAMETER Target, Payload, or RedResponse is NULL.
|
|
@retval EFI_DEVICE_ERROR An unexpected system or network error occurred. Callers can get
|
|
more error info from returned HTTP StatusCode, Headers and Payload
|
|
within RedResponse:
|
|
1. If the returned StatusCode is NULL, indicates any error happen.
|
|
2. If the returned StatusCode is not NULL and the value is not 2XX,
|
|
indicates any error happen.
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
RedfishPostToPayload (
|
|
IN REDFISH_PAYLOAD Target,
|
|
IN REDFISH_PAYLOAD Payload,
|
|
OUT REDFISH_RESPONSE *RedResponse
|
|
)
|
|
{
|
|
if ((Target == NULL) || (Payload == NULL) || (RedResponse == NULL)) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
ZeroMem (RedResponse, sizeof (REDFISH_RESPONSE));
|
|
|
|
RedResponse->Payload = (REDFISH_PAYLOAD)postPayload (
|
|
Target,
|
|
Payload,
|
|
&(RedResponse->StatusCode)
|
|
);
|
|
|
|
//
|
|
// 1. If the returned StatusCode is NULL, indicates any error happen.
|
|
//
|
|
if (RedResponse->StatusCode == NULL) {
|
|
return EFI_DEVICE_ERROR;
|
|
}
|
|
|
|
//
|
|
// 2. If the returned StatusCode is not NULL and the value is not 2XX, indicates any error happen.
|
|
// NOTE: If there is any error message returned from server, it will be returned in
|
|
// Payload within RedResponse.
|
|
//
|
|
if ((*(RedResponse->StatusCode) < HTTP_STATUS_200_OK) || \
|
|
(*(RedResponse->StatusCode) > HTTP_STATUS_206_PARTIAL_CONTENT))
|
|
{
|
|
return EFI_DEVICE_ERROR;
|
|
}
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
Use HTTP DELETE to remove a resource.
|
|
|
|
This function uses the RedfishService to remove a Redfish resource which is addressed
|
|
by input Uri (only the relative path is required). The corresponding redfish response will
|
|
returned, including HTTP StatusCode, Headers and Payload which record any HTTP response
|
|
messages.
|
|
|
|
Callers are responsible for freeing the HTTP StatusCode, Headers and Payload returned in
|
|
redfish response data.
|
|
|
|
@param[in] RedfishService The Service to access the Redfish resources.
|
|
@param[in] Uri Relative path to address the resource.
|
|
@param[out] RedResponse Pointer to the Redfish response data.
|
|
|
|
@retval EFI_SUCCESS The opeartion is successful, indicates the HTTP StatusCode is not
|
|
NULL and the value is 2XX, the Redfish resource has been removed.
|
|
If there is any message returned from server, it will be returned
|
|
in Payload within RedResponse.
|
|
@retval EFI_INVALID_PARAMETER RedfishService, Uri, or RedResponse is NULL.
|
|
@retval EFI_DEVICE_ERROR An unexpected system or network error occurred. Callers can get
|
|
more error info from returned HTTP StatusCode, Headers and Payload
|
|
within RedResponse:
|
|
1. If the returned StatusCode is NULL, indicates any error happen.
|
|
2. If the returned StatusCode is not NULL and the value is not 2XX,
|
|
indicates any error happen.
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
RedfishDeleteByUri (
|
|
IN REDFISH_SERVICE RedfishService,
|
|
IN CONST CHAR8 *Uri,
|
|
OUT REDFISH_RESPONSE *RedResponse
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
EDKII_JSON_VALUE JsonValue;
|
|
|
|
Status = EFI_SUCCESS;
|
|
JsonValue = NULL;
|
|
|
|
if ((RedfishService == NULL) || (Uri == NULL) || (RedResponse == NULL)) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
ZeroMem (RedResponse, sizeof (REDFISH_RESPONSE));
|
|
|
|
JsonValue = (EDKII_JSON_VALUE)deleteUriFromService (
|
|
RedfishService,
|
|
Uri,
|
|
&(RedResponse->StatusCode)
|
|
);
|
|
|
|
//
|
|
// 1. If the returned StatusCode is NULL, indicates any error happen.
|
|
//
|
|
if (RedResponse->StatusCode == NULL) {
|
|
Status = EFI_DEVICE_ERROR;
|
|
goto ON_EXIT;
|
|
}
|
|
|
|
//
|
|
// 2. If the returned StatusCode is not NULL and the value is not 2XX, indicates any error happen.
|
|
// NOTE: If there is any error message returned from server, it will be returned in
|
|
// Payload within RedResponse.
|
|
//
|
|
if ((*(RedResponse->StatusCode) < HTTP_STATUS_200_OK) || \
|
|
(*(RedResponse->StatusCode) > HTTP_STATUS_206_PARTIAL_CONTENT))
|
|
{
|
|
Status = EFI_DEVICE_ERROR;
|
|
}
|
|
|
|
ON_EXIT:
|
|
if (JsonValue != NULL) {
|
|
RedResponse->Payload = createRedfishPayload (JsonValue, RedfishService);
|
|
if (RedResponse->Payload == NULL) {
|
|
//
|
|
// Ignore the error when create RedfishPayload, just free the JsonValue since it's not what
|
|
// we care about if the returned StatusCode is 2XX.
|
|
//
|
|
JsonValueFree (JsonValue);
|
|
}
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
|
|
/**
|
|
Dump text in fractions.
|
|
|
|
@param[in] String ASCII string to dump.
|
|
|
|
**/
|
|
VOID
|
|
RedfishDumpJsonStringFractions (
|
|
IN CHAR8 *String
|
|
)
|
|
{
|
|
CHAR8 *NextFraction;
|
|
UINTN StringFractionSize;
|
|
UINTN StrLen;
|
|
UINTN Count;
|
|
CHAR8 BackupChar;
|
|
|
|
StringFractionSize = 200;
|
|
if (String == NULL) {
|
|
return;
|
|
}
|
|
|
|
DEBUG ((DEBUG_INFO, "JSON text:\n"));
|
|
NextFraction = String;
|
|
StrLen = AsciiStrLen (String);
|
|
if (StrLen == 0) {
|
|
return;
|
|
}
|
|
|
|
for (Count = 0; Count < (StrLen / StringFractionSize); Count++) {
|
|
BackupChar = *(NextFraction + StringFractionSize);
|
|
*(NextFraction + StringFractionSize) = 0;
|
|
DEBUG ((DEBUG_INFO, "%a", NextFraction));
|
|
*(NextFraction + StringFractionSize) = BackupChar;
|
|
NextFraction += StringFractionSize;
|
|
}
|
|
|
|
if ((StrLen % StringFractionSize) != 0) {
|
|
DEBUG ((DEBUG_INFO, "%a\n\n", NextFraction));
|
|
}
|
|
}
|
|
|
|
/**
|
|
Dump text in JSON value.
|
|
|
|
@param[in] JsonValue The Redfish JSON value to dump.
|
|
|
|
**/
|
|
VOID
|
|
RedfishDumpJson (
|
|
IN EDKII_JSON_VALUE JsonValue
|
|
)
|
|
{
|
|
CHAR8 *String;
|
|
|
|
String = JsonDumpString (JsonValue, 0);
|
|
if (String == NULL) {
|
|
return;
|
|
}
|
|
|
|
RedfishDumpJsonStringFractions (String);
|
|
FreePool (String);
|
|
}
|
|
|
|
/**
|
|
Extract the JSON text content from REDFISH_PAYLOAD and dump to debug console.
|
|
|
|
@param[in] Payload The Redfish payload to dump.
|
|
|
|
**/
|
|
VOID
|
|
RedfishDumpPayload (
|
|
IN REDFISH_PAYLOAD Payload
|
|
)
|
|
{
|
|
EDKII_JSON_VALUE JsonValue;
|
|
CHAR8 *String;
|
|
|
|
JsonValue = NULL;
|
|
String = NULL;
|
|
|
|
if (Payload == NULL) {
|
|
return;
|
|
}
|
|
|
|
JsonValue = RedfishJsonInPayload (Payload);
|
|
if (JsonValue == NULL) {
|
|
return;
|
|
}
|
|
|
|
String = JsonDumpString (JsonValue, 0);
|
|
if (String == NULL) {
|
|
return;
|
|
}
|
|
|
|
RedfishDumpJsonStringFractions (String);
|
|
FreePool (String);
|
|
}
|
|
|
|
/**
|
|
This function will cleanup the HTTP header and Redfish payload resources.
|
|
|
|
@param[in] StatusCode The status code in HTTP response message.
|
|
@param[in] HeaderCount Number of HTTP header structures in Headers list.
|
|
@param[in] Headers Array containing list of HTTP headers.
|
|
@param[in] Payload The Redfish payload to dump.
|
|
|
|
**/
|
|
VOID
|
|
RedfishFreeResponse (
|
|
IN EFI_HTTP_STATUS_CODE *StatusCode,
|
|
IN UINTN HeaderCount,
|
|
IN EFI_HTTP_HEADER *Headers,
|
|
IN REDFISH_PAYLOAD Payload
|
|
)
|
|
{
|
|
if (StatusCode != NULL) {
|
|
FreePool (StatusCode);
|
|
StatusCode = NULL;
|
|
}
|
|
|
|
if ((HeaderCount != 0) && (Headers != NULL)) {
|
|
HttpFreeHeaderFields (Headers, HeaderCount);
|
|
Headers = NULL;
|
|
}
|
|
|
|
if (Payload != NULL) {
|
|
RedfishCleanupPayload (Payload);
|
|
Payload = NULL;
|
|
}
|
|
}
|
|
|
|
/**
|
|
Check if the "@odata.type" in Payload is valid or not.
|
|
|
|
@param[in] Payload The Redfish payload to be checked.
|
|
@param[in] OdataTypeName OdataType will be retrived from mapping list.
|
|
@param[in] OdataTypeMappingList The list of OdataType.
|
|
@param[in] OdataTypeMappingListSize The number of mapping list
|
|
|
|
@return TRUE if the "@odata.type" in Payload is valid, otherwise FALSE.
|
|
|
|
**/
|
|
BOOLEAN
|
|
RedfishIsValidOdataType (
|
|
IN REDFISH_PAYLOAD Payload,
|
|
IN CONST CHAR8 *OdataTypeName,
|
|
IN REDFISH_ODATA_TYPE_MAPPING *OdataTypeMappingList,
|
|
IN UINTN OdataTypeMappingListSize
|
|
)
|
|
{
|
|
UINTN Index;
|
|
EDKII_JSON_VALUE OdataType;
|
|
EDKII_JSON_VALUE JsonValue;
|
|
|
|
if ((Payload == NULL) || (OdataTypeName == NULL)) {
|
|
return FALSE;
|
|
}
|
|
|
|
JsonValue = RedfishJsonInPayload (Payload);
|
|
if (!JsonValueIsObject (JsonValue)) {
|
|
return FALSE;
|
|
}
|
|
|
|
OdataType = JsonObjectGetValue (JsonValueGetObject (JsonValue), "@odata.type");
|
|
if (!JsonValueIsString (OdataType) || (JsonValueGetAsciiString (OdataType) == NULL)) {
|
|
return FALSE;
|
|
}
|
|
|
|
for (Index = 0; Index < OdataTypeMappingListSize; Index++) {
|
|
if ((AsciiStrCmp (OdataTypeMappingList[Index].OdataTypeName, OdataTypeName) == 0) &&
|
|
(AsciiStrCmp (OdataTypeMappingList[Index].OdataType, JsonValueGetAsciiString (OdataType)) == 0))
|
|
{
|
|
return TRUE;
|
|
}
|
|
}
|
|
|
|
DEBUG ((DEBUG_INFO, "%a: This Odata type is not in the list.\n", __FUNCTION__));
|
|
return FALSE;
|
|
}
|
|
|
|
/**
|
|
Check if the payload is collection
|
|
|
|
@param[in] Payload The Redfish payload to be checked.
|
|
|
|
@return TRUE if the payload is collection.
|
|
|
|
**/
|
|
BOOLEAN
|
|
RedfishIsPayloadCollection (
|
|
IN REDFISH_PAYLOAD Payload
|
|
)
|
|
{
|
|
return isPayloadCollection (Payload);
|
|
}
|
|
|
|
/**
|
|
Get collection size.
|
|
|
|
@param[in] Payload The Redfish collection payload
|
|
@param[in] CollectionSize Size of this collection
|
|
|
|
@return EFI_SUCCESS Coolection size is returned in CollectionSize
|
|
@return EFI_INVALID_PARAMETER The payload is not a collection.
|
|
**/
|
|
EFI_STATUS
|
|
RedfishGetCollectionSize (
|
|
IN REDFISH_PAYLOAD Payload,
|
|
IN UINTN *CollectionSize
|
|
)
|
|
{
|
|
if ((Payload == NULL) || (CollectionSize == NULL)) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
if (!RedfishIsPayloadCollection (Payload)) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
*CollectionSize = (UINTN)getCollectionSize (Payload);
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
Get Redfish payload of collection member
|
|
|
|
@param[in] Payload The Redfish collection payload
|
|
@param[in] Index Index of collection member
|
|
|
|
@return NULL Fail to get collection member.
|
|
@return Non NULL Payload is returned.
|
|
**/
|
|
REDFISH_PAYLOAD
|
|
RedfishGetPayloadByIndex (
|
|
IN REDFISH_PAYLOAD Payload,
|
|
IN UINTN Index
|
|
)
|
|
{
|
|
REDFISH_RESPONSE RedfishResponse;
|
|
REDFISH_PAYLOAD PayloadReturn;
|
|
|
|
PayloadReturn = (VOID *)getPayloadByIndex (Payload, Index, &RedfishResponse.StatusCode);
|
|
if ((PayloadReturn == NULL) ||
|
|
((*(RedfishResponse.StatusCode) < HTTP_STATUS_200_OK) && (*(RedfishResponse.StatusCode) > HTTP_STATUS_206_PARTIAL_CONTENT)))
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
return PayloadReturn;
|
|
}
|
|
|
|
/**
|
|
Check and return Redfish resource of the given Redpath.
|
|
|
|
@param[in] RedfishService Pointer to REDFISH_SERVICE
|
|
@param[in] Redpath Redpath of the resource.
|
|
@param[in] Response Optional return the resource.
|
|
|
|
@return EFI_STATUS
|
|
**/
|
|
EFI_STATUS
|
|
RedfishCheckIfRedpathExist (
|
|
IN REDFISH_SERVICE RedfishService,
|
|
IN CHAR8 *Redpath,
|
|
IN REDFISH_RESPONSE *Response OPTIONAL
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
REDFISH_RESPONSE TempResponse;
|
|
|
|
if (Redpath == NULL) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
Status = RedfishGetByService (RedfishService, Redpath, &TempResponse);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
|
|
if (Response == NULL) {
|
|
RedfishFreeResponse (
|
|
TempResponse.StatusCode,
|
|
TempResponse.HeaderCount,
|
|
TempResponse.Headers,
|
|
TempResponse.Payload
|
|
);
|
|
} else {
|
|
CopyMem ((VOID *)Response, (VOID *)&TempResponse, sizeof (REDFISH_RESPONSE));
|
|
}
|
|
|
|
return EFI_SUCCESS;
|
|
}
|