1 /** 2 * Copyright © 2019 IBM Corporation 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 #include "user_header.hpp" 17 18 #include "pel_types.hpp" 19 #include "pel_values.hpp" 20 #include "severity.hpp" 21 22 #include <iostream> 23 #include <phosphor-logging/log.hpp> 24 25 namespace openpower 26 { 27 namespace pels 28 { 29 30 namespace pv = openpower::pels::pel_values; 31 using namespace phosphor::logging; 32 33 void UserHeader::unflatten(Stream& stream) 34 { 35 stream >> _header >> _eventSubsystem >> _eventScope >> _eventSeverity >> 36 _eventType >> _reserved4Byte1 >> _problemDomain >> _problemVector >> 37 _actionFlags >> _reserved4Byte2; 38 } 39 40 void UserHeader::flatten(Stream& stream) const 41 { 42 stream << _header << _eventSubsystem << _eventScope << _eventSeverity 43 << _eventType << _reserved4Byte1 << _problemDomain << _problemVector 44 << _actionFlags << _reserved4Byte2; 45 } 46 47 UserHeader::UserHeader(const message::Entry& entry, 48 phosphor::logging::Entry::Level severity) 49 { 50 _header.id = static_cast<uint16_t>(SectionID::userHeader); 51 _header.size = UserHeader::flattenedSize(); 52 _header.version = userHeaderVersion; 53 _header.subType = 0; 54 _header.componentID = static_cast<uint16_t>(ComponentID::phosphorLogging); 55 56 _eventSubsystem = entry.subsystem; 57 58 _eventScope = entry.eventScope.value_or( 59 static_cast<uint8_t>(EventScope::entirePlatform)); 60 61 // Get the severity from the registry if it's there, otherwise get it 62 // from the OpenBMC event log severity value. 63 _eventSeverity = 64 entry.severity.value_or(convertOBMCSeverityToPEL(severity)); 65 66 // TODO: ibm-dev/dev/#1144 Handle manufacturing sev & action flags 67 68 if (entry.eventType) 69 { 70 _eventType = *entry.eventType; 71 } 72 else 73 { 74 // There are different default event types for info errors 75 // vs non info ones. 76 auto sevType = static_cast<SeverityType>(_eventSeverity & 0xF0); 77 78 _eventType = (sevType == SeverityType::nonError) 79 ? static_cast<uint8_t>(EventType::miscInformational) 80 : static_cast<uint8_t>(EventType::notApplicable); 81 } 82 83 _reserved4Byte1 = 0; 84 85 // No uses for problem domain or vector 86 _problemDomain = 0; 87 _problemVector = 0; 88 89 // These will be cleaned up later in pel_rules::check() 90 _actionFlags = entry.actionFlags.value_or(0); 91 92 _reserved4Byte2 = 0; 93 94 _valid = true; 95 } 96 97 UserHeader::UserHeader(Stream& pel) 98 { 99 try 100 { 101 unflatten(pel); 102 validate(); 103 } 104 catch (const std::exception& e) 105 { 106 log<level::ERR>("Cannot unflatten user header", 107 entry("ERROR=%s", e.what())); 108 _valid = false; 109 } 110 } 111 112 void UserHeader::validate() 113 { 114 bool failed = false; 115 if (header().id != static_cast<uint16_t>(SectionID::userHeader)) 116 { 117 log<level::ERR>("Invalid user header section ID", 118 entry("ID=0x%X", header().id)); 119 failed = true; 120 } 121 122 if (header().version != userHeaderVersion) 123 { 124 log<level::ERR>("Invalid user header version", 125 entry("VERSION=0x%X", header().version)); 126 failed = true; 127 } 128 129 _valid = (failed) ? false : true; 130 } 131 132 std::optional<std::string> UserHeader::getJSON() const 133 { 134 std::string severity; 135 std::string subsystem; 136 std::string eventScope; 137 std::string eventType; 138 severity = pv::getValue(_eventSeverity, pel_values::severityValues); 139 subsystem = pv::getValue(_eventSubsystem, pel_values::subsystemValues); 140 eventScope = pv::getValue(_eventScope, pel_values::eventScopeValues); 141 eventType = pv::getValue(_eventType, pel_values::eventTypeValues); 142 char tmpUhVal[8]; 143 sprintf(tmpUhVal, "%d", userHeaderVersion); 144 std::string uhVerStr(tmpUhVal); 145 sprintf(tmpUhVal, "0x%X", _header.componentID); 146 std::string uhCbStr(tmpUhVal); 147 sprintf(tmpUhVal, "%d", _header.subType); 148 std::string uhStStr(tmpUhVal); 149 150 std::string uh = "{\"Section Version\": \"" + uhVerStr + 151 "\"}, \n {\"Sub-section type\": \"" + uhStStr + 152 "\"}, \n " 153 "{\"Log Committed by\": \"" + 154 uhCbStr + "\"}, \n {\"Subsystem\": \"" + subsystem + 155 "\"},\n " 156 "{\"Event Scope\": \"" + 157 eventScope + "\"}, \n {\"Event Severity\":\"" + severity + 158 "\"},\n {\"Event Type\": \"" + eventType + "\"}"; 159 return uh; 160 } 161 } // namespace pels 162 } // namespace openpower 163