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 "json_utils.hpp" 19 #include "pel_types.hpp" 20 #include "pel_values.hpp" 21 #include "severity.hpp" 22 23 #include <iostream> 24 #include <phosphor-logging/log.hpp> 25 26 namespace openpower 27 { 28 namespace pels 29 { 30 31 namespace pv = openpower::pels::pel_values; 32 using namespace phosphor::logging; 33 34 void UserHeader::unflatten(Stream& stream) 35 { 36 stream >> _header >> _eventSubsystem >> _eventScope >> _eventSeverity >> 37 _eventType >> _reserved4Byte1 >> _problemDomain >> _problemVector >> 38 _actionFlags >> _states; 39 } 40 41 void UserHeader::flatten(Stream& stream) const 42 { 43 stream << _header << _eventSubsystem << _eventScope << _eventSeverity 44 << _eventType << _reserved4Byte1 << _problemDomain << _problemVector 45 << _actionFlags << _states; 46 } 47 48 UserHeader::UserHeader(const message::Entry& entry, 49 phosphor::logging::Entry::Level severity) 50 { 51 _header.id = static_cast<uint16_t>(SectionID::userHeader); 52 _header.size = UserHeader::flattenedSize(); 53 _header.version = userHeaderVersion; 54 _header.subType = 0; 55 _header.componentID = static_cast<uint16_t>(ComponentID::phosphorLogging); 56 57 _eventSubsystem = entry.subsystem; 58 59 _eventScope = entry.eventScope.value_or( 60 static_cast<uint8_t>(EventScope::entirePlatform)); 61 62 // Get the severity from the registry if it's there, otherwise get it 63 // from the OpenBMC event log severity value. 64 _eventSeverity = 65 entry.severity.value_or(convertOBMCSeverityToPEL(severity)); 66 67 // TODO: ibm-dev/dev/#1144 Handle manufacturing sev & action flags 68 69 if (entry.eventType) 70 { 71 _eventType = *entry.eventType; 72 } 73 else 74 { 75 // There are different default event types for info errors 76 // vs non info ones. 77 auto sevType = static_cast<SeverityType>(_eventSeverity & 0xF0); 78 79 _eventType = (sevType == SeverityType::nonError) 80 ? static_cast<uint8_t>(EventType::miscInformational) 81 : static_cast<uint8_t>(EventType::notApplicable); 82 } 83 84 _reserved4Byte1 = 0; 85 86 // No uses for problem domain or vector 87 _problemDomain = 0; 88 _problemVector = 0; 89 90 // These will be cleaned up later in pel_rules::check() 91 _actionFlags = entry.actionFlags.value_or(0); 92 93 _states = 0; 94 95 _valid = true; 96 } 97 98 UserHeader::UserHeader(Stream& pel) 99 { 100 try 101 { 102 unflatten(pel); 103 validate(); 104 } 105 catch (const std::exception& e) 106 { 107 log<level::ERR>("Cannot unflatten user header", 108 entry("ERROR=%s", e.what())); 109 _valid = false; 110 } 111 } 112 113 void UserHeader::validate() 114 { 115 bool failed = false; 116 if (header().id != static_cast<uint16_t>(SectionID::userHeader)) 117 { 118 log<level::ERR>("Invalid user header section ID", 119 entry("ID=0x%X", header().id)); 120 failed = true; 121 } 122 123 if (header().version != userHeaderVersion) 124 { 125 log<level::ERR>("Invalid user header version", 126 entry("VERSION=0x%X", header().version)); 127 failed = true; 128 } 129 130 _valid = (failed) ? false : true; 131 } 132 133 std::optional<std::string> UserHeader::getJSON() const 134 { 135 std::string severity; 136 std::string subsystem; 137 std::string eventScope; 138 std::string eventType; 139 std::vector<std::string> actionFlags; 140 severity = pv::getValue(_eventSeverity, pel_values::severityValues); 141 subsystem = pv::getValue(_eventSubsystem, pel_values::subsystemValues); 142 eventScope = pv::getValue(_eventScope, pel_values::eventScopeValues); 143 eventType = pv::getValue(_eventType, pel_values::eventTypeValues); 144 actionFlags = 145 pv::getValuesBitwise(_actionFlags, pel_values::actionFlagsValues); 146 147 std::string hostState{"Invalid"}; 148 auto iter = pv::transmissionStates.find( 149 static_cast<TransmissionState>(hostTransmissionState())); 150 if (iter != pv::transmissionStates.end()) 151 { 152 hostState = iter->second; 153 } 154 155 std::string uh; 156 jsonInsert(uh, pv::sectionVer, getNumberString("%d", userHeaderVersion), 1); 157 jsonInsert(uh, pv::subSection, getNumberString("%d", _header.subType), 1); 158 jsonInsert(uh, "Log Committed by", 159 getNumberString("0x%X", _header.componentID), 1); 160 jsonInsert(uh, "Subsystem", subsystem, 1); 161 jsonInsert(uh, "Event Scope", eventScope, 1); 162 jsonInsert(uh, "Event Severity", severity, 1); 163 jsonInsert(uh, "Event Type", eventType, 1); 164 jsonInsertArray(uh, "Action Flags", actionFlags, 1); 165 jsonInsert(uh, "Host Transmission", hostState, 1); 166 uh.erase(uh.size() - 2); 167 return uh; 168 } 169 } // namespace pels 170 } // namespace openpower 171