Remove validation bits
Discard invalid properties from json decode. JSON output should only
contain valid properties. This saves time in preventing post
processing of output for valid fields.
Ensure round trip validity with validation bits removed and required
properties populated.
Fix bugs in json decode.
Overhaul unit tests to use valijson. Add tests with static examples
to validate against schema. Use and nlohmann for better schema
validation over intrinsic libcper validation.
Example json output before:
{
"ValidationBits": {
"LevelValid": false,
"CorrectedValid": true
},
"Level": 1,
"Corrected": true
}
After:
{
"Corrected": true
}
Change-Id: I188bdc2827a57d938c22a431238fadfcdc939ab8
Signed-off-by: Aushim Nagarkatti <anagarkatti@nvidia.com>
diff --git a/sections/cper-section-ccix-per.c b/sections/cper-section-ccix-per.c
index 9081fe2..6f85939 100644
--- a/sections/cper-section-ccix-per.c
+++ b/sections/cper-section-ccix-per.c
@@ -17,39 +17,46 @@
{
EFI_CCIX_PER_LOG_DATA *ccix_error = (EFI_CCIX_PER_LOG_DATA *)section;
json_object *section_ir = json_object_new_object();
+ ValidationTypes ui64Type = { UINT_64T,
+ .value.ui64 = ccix_error->ValidBits };
//Length (bytes) for the entire structure.
json_object_object_add(section_ir, "length",
json_object_new_uint64(ccix_error->Length));
- //Validation bits.
- json_object *validation = bitfield_to_ir(
- ccix_error->ValidBits, 3, CCIX_PER_ERROR_VALID_BITFIELD_NAMES);
- json_object_object_add(section_ir, "validationBits", validation);
-
//CCIX source/port IDs.
- json_object_object_add(section_ir, "ccixSourceID",
- json_object_new_int(ccix_error->CcixSourceId));
- json_object_object_add(section_ir, "ccixPortID",
- json_object_new_int(ccix_error->CcixPortId));
+ if (isvalid_prop_to_ir(&ui64Type, 0)) {
+ json_object_object_add(
+ section_ir, "ccixSourceID",
+ json_object_new_int(ccix_error->CcixSourceId));
+ }
+ if (isvalid_prop_to_ir(&ui64Type, 1)) {
+ json_object_object_add(
+ section_ir, "ccixPortID",
+ json_object_new_int(ccix_error->CcixPortId));
+ }
//CCIX PER Log.
- //This is formatted as described in Section 7.3.2 of CCIX Base Specification (Rev 1.0).
- const char *cur_pos = (const char *)(ccix_error + 1);
- int remaining_length =
- ccix_error->Length - sizeof(EFI_CCIX_PER_LOG_DATA);
- if (remaining_length > 0) {
- int32_t encoded_len = 0;
+ if (isvalid_prop_to_ir(&ui64Type, 2)) {
+ //This is formatted as described in Section 7.3.2 of CCIX Base Specification (Rev 1.0).
+ const char *cur_pos = (const char *)(ccix_error + 1);
+ int remaining_length =
+ ccix_error->Length - sizeof(EFI_CCIX_PER_LOG_DATA);
+ if (remaining_length > 0) {
+ int32_t encoded_len = 0;
- char *encoded = base64_encode((UINT8 *)cur_pos,
- remaining_length, &encoded_len);
- if (encoded == NULL) {
- printf("Failed to allocate encode output buffer. \n");
- } else {
- json_object_object_add(section_ir, "ccixPERLog",
- json_object_new_string_len(
- encoded, encoded_len));
- free(encoded);
+ char *encoded = base64_encode((UINT8 *)cur_pos,
+ remaining_length,
+ &encoded_len);
+ if (encoded == NULL) {
+ printf("Failed to allocate encode output buffer. \n");
+ } else {
+ json_object_object_add(
+ section_ir, "ccixPERLog",
+ json_object_new_string_len(
+ encoded, encoded_len));
+ free(encoded);
+ }
}
}
@@ -62,6 +69,9 @@
EFI_CCIX_PER_LOG_DATA *section_cper = (EFI_CCIX_PER_LOG_DATA *)calloc(
1, sizeof(EFI_CCIX_PER_LOG_DATA));
+ ValidationTypes ui64Type = { UINT_64T, .value.ui64 = 0 };
+ struct json_object *obj = NULL;
+
//Length.
section_cper->Length = json_object_get_uint64(
json_object_object_get(section, "length"));
@@ -72,28 +82,41 @@
CCIX_PER_ERROR_VALID_BITFIELD_NAMES);
//CCIX source/port IDs.
- section_cper->CcixSourceId = (UINT8)json_object_get_int(
- json_object_object_get(section, "ccixSourceID"));
- section_cper->CcixPortId = (UINT8)json_object_get_int(
- json_object_object_get(section, "ccixPortID"));
+ if (json_object_object_get_ex(section, "ccixSourceID", &obj)) {
+ section_cper->CcixSourceId = (UINT8)json_object_get_int(obj);
+ add_to_valid_bitfield(&ui64Type, 0);
+ }
+ if (json_object_object_get_ex(section, "ccixPortID", &obj)) {
+ section_cper->CcixPortId = (UINT8)json_object_get_int(obj);
+ add_to_valid_bitfield(&ui64Type, 1);
+ }
+
+ bool perlog_exists = false;
+ if (json_object_object_get_ex(section, "ccixPERLog", &obj)) {
+ perlog_exists = true;
+ add_to_valid_bitfield(&ui64Type, 2);
+ }
+ section_cper->ValidBits = ui64Type.value.ui64;
//Write header out to stream.
fwrite(section_cper, sizeof(EFI_CCIX_PER_LOG_DATA), 1, out);
fflush(out);
//Write CCIX PER log itself to stream.
- json_object *encoded = json_object_object_get(section, "ccixPERLog");
- int32_t decoded_len = 0;
+ if (perlog_exists) {
+ json_object *encoded = obj;
+ int32_t decoded_len = 0;
- UINT8 *decoded = base64_decode(json_object_get_string(encoded),
- json_object_get_string_len(encoded),
- &decoded_len);
- if (decoded == NULL) {
- printf("Failed to allocate decode output buffer. \n");
- } else {
- fwrite(decoded, decoded_len, 1, out);
- fflush(out);
- free(decoded);
+ UINT8 *decoded = base64_decode(
+ json_object_get_string(encoded),
+ json_object_get_string_len(encoded), &decoded_len);
+ if (decoded == NULL) {
+ printf("Failed to allocate decode output buffer. \n");
+ } else {
+ fwrite(decoded, decoded_len, 1, out);
+ fflush(out);
+ free(decoded);
+ }
}
//Free resources.
free(section_cper);