Lawrence Tang | f0f9557 | 2022-07-07 16:56:22 +0100 | [diff] [blame] | 1 | /** |
| 2 | * Describes functions for parsing JSON IR CPER data into binary CPER format. |
| 3 | * |
| 4 | * Author: Lawrence.Tang@arm.com |
| 5 | **/ |
| 6 | |
| 7 | #include <stdio.h> |
| 8 | #include "json.h" |
Lawrence Tang | b44314c | 2022-07-13 11:45:22 +0100 | [diff] [blame^] | 9 | #include "edk/Cper.h" |
Lawrence Tang | f0f9557 | 2022-07-07 16:56:22 +0100 | [diff] [blame] | 10 | #include "cper-parse.h" |
Lawrence Tang | b44314c | 2022-07-13 11:45:22 +0100 | [diff] [blame^] | 11 | #include "cper-utils.h" |
| 12 | |
| 13 | //Private pre-declarations. |
| 14 | void ir_header_to_cper(json_object* header_ir, EFI_COMMON_ERROR_RECORD_HEADER* header); |
Lawrence Tang | f0f9557 | 2022-07-07 16:56:22 +0100 | [diff] [blame] | 15 | |
| 16 | //Converts the given JSON IR CPER representation into CPER binary format, piped to the provided file stream. |
Lawrence Tang | b44314c | 2022-07-13 11:45:22 +0100 | [diff] [blame^] | 17 | //This function performs no validation of the IR against the CPER-JSON specification. For this, call |
| 18 | //validate_schema() from json-schema.h before attempting to call this function. |
Lawrence Tang | f0f9557 | 2022-07-07 16:56:22 +0100 | [diff] [blame] | 19 | void ir_to_cper(json_object* ir, FILE* out) |
| 20 | { |
Lawrence Tang | b44314c | 2022-07-13 11:45:22 +0100 | [diff] [blame^] | 21 | //Create the CPER header. |
| 22 | EFI_COMMON_ERROR_RECORD_HEADER* header = (EFI_COMMON_ERROR_RECORD_HEADER*)calloc(1, sizeof(EFI_COMMON_ERROR_RECORD_HEADER)); |
| 23 | ir_header_to_cper(json_object_object_get(ir, "header"), header); |
| 24 | fwrite(header, sizeof(EFI_COMMON_ERROR_RECORD_HEADER), 1, out); |
| 25 | |
Lawrence Tang | f0f9557 | 2022-07-07 16:56:22 +0100 | [diff] [blame] | 26 | //... |
Lawrence Tang | b44314c | 2022-07-13 11:45:22 +0100 | [diff] [blame^] | 27 | |
| 28 | //Free all resources. |
| 29 | fflush(out); |
| 30 | free(header); |
| 31 | } |
| 32 | |
| 33 | //Converts a CPER-JSON IR header to a CPER header structure. |
| 34 | void ir_header_to_cper(json_object* header_ir, EFI_COMMON_ERROR_RECORD_HEADER* header) |
| 35 | { |
| 36 | header->SignatureStart = 0x52455043; //CPER |
| 37 | printf("beginning write.\n"); |
| 38 | |
| 39 | //Revision. |
| 40 | json_object* revision = json_object_object_get(header_ir, "revision"); |
| 41 | int minor = json_object_get_int(json_object_object_get(revision, "minor")); |
| 42 | int major = json_object_get_int(json_object_object_get(revision, "major")); |
| 43 | header->Revision = minor + (major << 8); |
| 44 | |
| 45 | header->SignatureEnd = 0xFFFFFFFF; |
| 46 | |
| 47 | //Section count. |
| 48 | int section_count = json_object_get_int(json_object_object_get(header_ir, "sectionCount")); |
| 49 | header->SectionCount = (UINT16)section_count; |
| 50 | |
| 51 | //Error severity. |
| 52 | json_object* severity = json_object_object_get(header_ir, "severity"); |
| 53 | header->ErrorSeverity = (UINT32)json_object_get_uint64(json_object_object_get(severity, "code")); |
| 54 | |
| 55 | //Validation bits. |
| 56 | header->ValidationBits = ir_to_bitfield(json_object_object_get(header_ir, "validationBits"), |
| 57 | 3, CPER_HEADER_VALID_BITFIELD_NAMES); |
| 58 | |
| 59 | //Record length. |
| 60 | header->RecordLength = (UINT32)json_object_get_uint64(json_object_object_get(header_ir, "recordLength")); |
| 61 | |
| 62 | //Timestamp, if present. |
| 63 | printf("timestamp write.\n"); |
| 64 | json_object* timestamp = json_object_object_get(header_ir, "timestamp"); |
| 65 | if (timestamp != NULL) |
| 66 | { |
| 67 | string_to_timestamp(&header->TimeStamp, json_object_get_string(timestamp)); |
| 68 | header->TimeStamp.Flag = json_object_get_boolean(json_object_object_get(header_ir, "timestampIsPrecise")); |
| 69 | } |
| 70 | |
| 71 | //Various GUIDs. |
| 72 | printf("guid write.\n"); |
| 73 | json_object* platform_id = json_object_object_get(header_ir, "platformID"); |
| 74 | json_object* partition_id = json_object_object_get(header_ir, "partitionID"); |
| 75 | if (platform_id != NULL) |
| 76 | string_to_guid(&header->PlatformID, json_object_get_string(platform_id)); |
| 77 | if (partition_id != NULL) |
| 78 | string_to_guid(&header->PartitionID, json_object_get_string(partition_id)); |
| 79 | string_to_guid(&header->CreatorID, json_object_get_string(json_object_object_get(header_ir, "creatorID"))); |
| 80 | |
| 81 | //Notification type. |
| 82 | printf("notif type write.\n"); |
| 83 | json_object* notification_type = json_object_object_get(header_ir, "notificationType"); |
| 84 | string_to_guid(&header->NotificationType, json_object_get_string(json_object_object_get(notification_type, "guid"))); |
| 85 | |
| 86 | //Record ID, persistence info. |
| 87 | header->RecordID = json_object_get_uint64(json_object_object_get(header_ir, "recordID")); |
| 88 | header->PersistenceInfo = json_object_get_uint64(json_object_object_get(header_ir, "persistenceInfo")); |
| 89 | |
| 90 | //Flags. |
| 91 | printf("flag write.\n"); |
| 92 | json_object* flags = json_object_object_get(header_ir, "flags"); |
| 93 | header->Flags = (UINT32)json_object_get_uint64(json_object_object_get(flags, "value")); |
Lawrence Tang | f0f9557 | 2022-07-07 16:56:22 +0100 | [diff] [blame] | 94 | } |