/** @file | |
Redfish debug library to debug Redfish application. | |
Copyright (c) 2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved. | |
SPDX-License-Identifier: BSD-2-Clause-Patent | |
**/ | |
#include <Uefi.h> | |
#include <Library/BaseLib.h> | |
#include <Library/DebugLib.h> | |
#include <Library/MemoryAllocationLib.h> | |
#include <Library/RedfishDebugLib.h> | |
#include <Library/UefiLib.h> | |
#ifndef IS_EMPTY_STRING | |
#define IS_EMPTY_STRING(a) ((a) == NULL || (a)[0] == '\0') | |
#endif | |
#define REDFISH_JSON_STRING_LENGTH 200 | |
#define REDFISH_JSON_OUTPUT_FORMAT (EDKII_JSON_COMPACT | EDKII_JSON_INDENT(2)) | |
/** | |
Debug print the value of StatementValue. | |
@param[in] ErrorLevel DEBUG macro error level. | |
@param[in] StatementValue The statement value to print. | |
@retval EFI_SUCCESS StatementValue is printed. | |
@retval EFI_INVALID_PARAMETER StatementValue is NULL. | |
**/ | |
EFI_STATUS | |
DumpHiiStatementValue ( | |
IN UINTN ErrorLevel, | |
IN HII_STATEMENT_VALUE *StatementValue | |
) | |
{ | |
if (StatementValue == NULL) { | |
return EFI_INVALID_PARAMETER; | |
} | |
DEBUG ((ErrorLevel, "BufferValueType: 0x%x\n", StatementValue->BufferValueType)); | |
DEBUG ((ErrorLevel, "BufferLen: 0x%x\n", StatementValue->BufferLen)); | |
DEBUG ((ErrorLevel, "Buffer: 0x%p\n", StatementValue->Buffer)); | |
DEBUG ((ErrorLevel, "Type: 0x%p\n", StatementValue->Type)); | |
switch (StatementValue->Type) { | |
case EFI_IFR_TYPE_NUM_SIZE_8: | |
DEBUG ((ErrorLevel, "Value: 0x%x\n", StatementValue->Value.u8)); | |
break; | |
case EFI_IFR_TYPE_NUM_SIZE_16: | |
DEBUG ((ErrorLevel, "Value: 0x%x\n", StatementValue->Value.u16)); | |
break; | |
case EFI_IFR_TYPE_NUM_SIZE_32: | |
DEBUG ((ErrorLevel, "Value: 0x%x\n", StatementValue->Value.u32)); | |
break; | |
case EFI_IFR_TYPE_NUM_SIZE_64: | |
DEBUG ((ErrorLevel, "Value: 0x%lx\n", StatementValue->Value.u64)); | |
break; | |
case EFI_IFR_TYPE_BOOLEAN: | |
DEBUG ((ErrorLevel, "Value: %a\n", (StatementValue->Value.b ? "true" : "false"))); | |
break; | |
case EFI_IFR_TYPE_STRING: | |
DEBUG ((ErrorLevel, "Value: 0x%x\n", StatementValue->Value.string)); | |
break; | |
case EFI_IFR_TYPE_TIME: | |
case EFI_IFR_TYPE_DATE: | |
default: | |
break; | |
} | |
return EFI_SUCCESS; | |
} | |
/** | |
Debug print the value of RedfishValue. | |
@param[in] ErrorLevel DEBUG macro error level. | |
@param[in] RedfishValue The statement value to print. | |
@retval EFI_SUCCESS RedfishValue is printed. | |
@retval EFI_INVALID_PARAMETER RedfishValue is NULL. | |
**/ | |
EFI_STATUS | |
DumpRedfishValue ( | |
IN UINTN ErrorLevel, | |
IN EDKII_REDFISH_VALUE *RedfishValue | |
) | |
{ | |
UINTN Index; | |
if (RedfishValue == NULL) { | |
return EFI_INVALID_PARAMETER; | |
} | |
DEBUG ((ErrorLevel, "Type: 0x%x\n", RedfishValue->Type)); | |
DEBUG ((ErrorLevel, "ArrayCount: 0x%x\n", RedfishValue->ArrayCount)); | |
switch (RedfishValue->Type) { | |
case RedfishValueTypeInteger: | |
DEBUG ((ErrorLevel, "Value: 0x%x\n", RedfishValue->Value.Integer)); | |
break; | |
case RedfishValueTypeBoolean: | |
DEBUG ((ErrorLevel, "Value: %a\n", (RedfishValue->Value.Boolean ? "true" : "false"))); | |
break; | |
case RedfishValueTypeString: | |
DEBUG ((ErrorLevel, "Value: %a\n", RedfishValue->Value.Buffer)); | |
break; | |
case RedfishValueTypeStringArray: | |
for (Index = 0; Index < RedfishValue->ArrayCount; Index++) { | |
DEBUG ((ErrorLevel, "Value[%d]: %a\n", Index, RedfishValue->Value.StringArray[Index])); | |
} | |
break; | |
case RedfishValueTypeIntegerArray: | |
for (Index = 0; Index < RedfishValue->ArrayCount; Index++) { | |
DEBUG ((ErrorLevel, "Value[%d]: 0x%x\n", Index, RedfishValue->Value.IntegerArray[Index])); | |
} | |
break; | |
case RedfishValueTypeBooleanArray: | |
for (Index = 0; Index < RedfishValue->ArrayCount; Index++) { | |
DEBUG ((ErrorLevel, "Value[%d]: %a\n", Index, (RedfishValue->Value.BooleanArray[Index] ? "true" : "false"))); | |
} | |
break; | |
case RedfishValueTypeUnknown: | |
case RedfishValueTypeMax: | |
default: | |
break; | |
} | |
return EFI_SUCCESS; | |
} | |
/** | |
This function dump the Json string in given error level. | |
@param[in] ErrorLevel DEBUG macro error level | |
@param[in] JsonValue Json value to dump. | |
@retval EFI_SUCCESS Json string is printed. | |
@retval Others Errors occur. | |
**/ | |
EFI_STATUS | |
DumpJsonValue ( | |
IN UINTN ErrorLevel, | |
IN EDKII_JSON_VALUE JsonValue | |
) | |
{ | |
CHAR8 *String; | |
CHAR8 *Runner; | |
CHAR8 Buffer[REDFISH_JSON_STRING_LENGTH + 1]; | |
UINTN StrLen; | |
UINTN Count; | |
UINTN Index; | |
if (JsonValue == NULL) { | |
return EFI_INVALID_PARAMETER; | |
} | |
String = JsonDumpString (JsonValue, REDFISH_JSON_OUTPUT_FORMAT); | |
if (String == NULL) { | |
return EFI_UNSUPPORTED; | |
} | |
StrLen = AsciiStrLen (String); | |
if (StrLen == 0) { | |
return EFI_UNSUPPORTED; | |
} | |
Count = StrLen / REDFISH_JSON_STRING_LENGTH; | |
Runner = String; | |
for (Index = 0; Index < Count; Index++) { | |
AsciiStrnCpyS (Buffer, (REDFISH_JSON_STRING_LENGTH + 1), Runner, REDFISH_JSON_STRING_LENGTH); | |
Buffer[REDFISH_JSON_STRING_LENGTH] = '\0'; | |
DEBUG ((ErrorLevel, "%a", Buffer)); | |
Runner += REDFISH_JSON_STRING_LENGTH; | |
} | |
Count = StrLen % REDFISH_JSON_STRING_LENGTH; | |
if (Count > 0) { | |
DEBUG ((ErrorLevel, "%a", Runner)); | |
} | |
DEBUG ((ErrorLevel, "\n")); | |
FreePool (String); | |
return EFI_SUCCESS; | |
} | |
/** | |
This function dump the status code, header and body in given | |
Redfish payload. | |
@param[in] ErrorLevel DEBUG macro error level | |
@param[in] Payload Redfish payload to dump | |
@retval EFI_SUCCESS Redfish payload is printed. | |
@retval Others Errors occur. | |
**/ | |
EFI_STATUS | |
DumpRedfishPayload ( | |
IN UINTN ErrorLevel, | |
IN REDFISH_PAYLOAD Payload | |
) | |
{ | |
EDKII_JSON_VALUE JsonValue; | |
if (Payload == NULL) { | |
return EFI_INVALID_PARAMETER; | |
} | |
JsonValue = RedfishJsonInPayload (Payload); | |
if (JsonValue != NULL) { | |
DEBUG ((ErrorLevel, "Payload:\n")); | |
DumpJsonValue (ErrorLevel, JsonValue); | |
} | |
return EFI_SUCCESS; | |
} | |
/** | |
This function dump the HTTP status code. | |
@param[in] ErrorLevel DEBUG macro error level | |
@param[in] HttpStatusCode HTTP status code | |
@retval EFI_SUCCESS HTTP status code is printed | |
**/ | |
EFI_STATUS | |
DumpHttpStatusCode ( | |
IN UINTN ErrorLevel, | |
IN EFI_HTTP_STATUS_CODE HttpStatusCode | |
) | |
{ | |
switch (HttpStatusCode) { | |
case HTTP_STATUS_100_CONTINUE: | |
DEBUG ((ErrorLevel, "Status code: 100 CONTINUE\n")); | |
break; | |
case HTTP_STATUS_200_OK: | |
DEBUG ((ErrorLevel, "Status code: 200 OK\n")); | |
break; | |
case HTTP_STATUS_201_CREATED: | |
DEBUG ((ErrorLevel, "Status code: 201 CREATED\n")); | |
break; | |
case HTTP_STATUS_202_ACCEPTED: | |
DEBUG ((ErrorLevel, "Status code: 202 ACCEPTED\n")); | |
break; | |
case HTTP_STATUS_304_NOT_MODIFIED: | |
DEBUG ((ErrorLevel, "Status code: 304 NOT MODIFIED\n")); | |
break; | |
case HTTP_STATUS_400_BAD_REQUEST: | |
DEBUG ((ErrorLevel, "Status code: 400 BAD REQUEST\n")); | |
break; | |
case HTTP_STATUS_401_UNAUTHORIZED: | |
DEBUG ((ErrorLevel, "Status code: 401 UNAUTHORIZED\n")); | |
break; | |
case HTTP_STATUS_403_FORBIDDEN: | |
DEBUG ((ErrorLevel, "Status code: 403 FORBIDDEN\n")); | |
break; | |
case HTTP_STATUS_404_NOT_FOUND: | |
DEBUG ((ErrorLevel, "Status code: 404 NOT FOUND\n")); | |
break; | |
case HTTP_STATUS_405_METHOD_NOT_ALLOWED: | |
DEBUG ((ErrorLevel, "Status code: 405 METHOD NOT ALLOWED\n")); | |
break; | |
case HTTP_STATUS_500_INTERNAL_SERVER_ERROR: | |
DEBUG ((ErrorLevel, "Status code: 500 INTERNAL SERVER ERROR\n")); | |
break; | |
default: | |
DEBUG ((ErrorLevel, "Status code: 0x%x\n", HttpStatusCode)); | |
break; | |
} | |
return EFI_SUCCESS; | |
} | |
/** | |
This function dump the status code, header and body in given | |
Redfish response. | |
@param[in] Message Message string | |
@param[in] ErrorLevel DEBUG macro error level | |
@param[in] Response Redfish response to dump | |
@retval EFI_SUCCESS Redfish response is printed. | |
@retval Others Errors occur. | |
**/ | |
EFI_STATUS | |
DumpRedfishResponse ( | |
IN CONST CHAR8 *Message, | |
IN UINTN ErrorLevel, | |
IN REDFISH_RESPONSE *Response | |
) | |
{ | |
UINTN Index; | |
if (Response == NULL) { | |
return EFI_INVALID_PARAMETER; | |
} | |
if (!IS_EMPTY_STRING (Message)) { | |
DEBUG ((ErrorLevel, "%a\n", Message)); | |
} | |
// | |
// status code | |
// | |
if (Response->StatusCode != NULL) { | |
DumpHttpStatusCode (ErrorLevel, *(Response->StatusCode)); | |
} | |
// | |
// header | |
// | |
if (Response->HeaderCount > 0) { | |
DEBUG ((ErrorLevel, "Header: %d\n", Response->HeaderCount)); | |
for (Index = 0; Index < Response->HeaderCount; Index++) { | |
DEBUG ((ErrorLevel, " %a: %a\n", Response->Headers[Index].FieldName, Response->Headers[Index].FieldValue)); | |
} | |
} | |
// | |
// Body | |
// | |
if (Response->Payload != NULL) { | |
DumpRedfishPayload (ErrorLevel, Response->Payload); | |
} | |
return EFI_SUCCESS; | |
} | |
/** | |
This function dump the IPv4 address in given error level. | |
@param[in] ErrorLevel DEBUG macro error level | |
@param[in] Ipv4Address IPv4 address to dump | |
@retval EFI_SUCCESS IPv4 address string is printed. | |
@retval Others Errors occur. | |
**/ | |
EFI_STATUS | |
DumpIpv4Address ( | |
IN UINTN ErrorLevel, | |
IN EFI_IPv4_ADDRESS *Ipv4Address | |
) | |
{ | |
if (Ipv4Address == NULL) { | |
return EFI_INVALID_PARAMETER; | |
} | |
DEBUG ((ErrorLevel, "%d.%d.%d.%d\n", Ipv4Address->Addr[0], Ipv4Address->Addr[1], Ipv4Address->Addr[2], Ipv4Address->Addr[3])); | |
return EFI_SUCCESS; | |
} |