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 "severity.hpp"
20 
21 #include <phosphor-logging/log.hpp>
22 
23 namespace openpower
24 {
25 namespace pels
26 {
27 
28 using namespace phosphor::logging;
29 
30 void UserHeader::unflatten(Stream& stream)
31 {
32     stream >> _header >> _eventSubsystem >> _eventScope >> _eventSeverity >>
33         _eventType >> _reserved4Byte1 >> _problemDomain >> _problemVector >>
34         _actionFlags >> _reserved4Byte2;
35 }
36 
37 void UserHeader::flatten(Stream& stream)
38 {
39     stream << _header << _eventSubsystem << _eventScope << _eventSeverity
40            << _eventType << _reserved4Byte1 << _problemDomain << _problemVector
41            << _actionFlags << _reserved4Byte2;
42 }
43 
44 UserHeader::UserHeader(const message::Entry& entry,
45                        phosphor::logging::Entry::Level severity)
46 {
47     _header.id = static_cast<uint16_t>(SectionID::userHeader);
48     _header.size = UserHeader::flattenedSize();
49     _header.version = userHeaderVersion;
50     _header.subType = 0;
51     _header.componentID = static_cast<uint16_t>(ComponentID::phosphorLogging);
52 
53     _eventSubsystem = entry.subsystem;
54 
55     _eventScope = entry.eventScope.value_or(
56         static_cast<uint8_t>(EventScope::entirePlatform));
57 
58     // Get the severity from the registry if it's there, otherwise get it
59     // from the OpenBMC event log severity value.
60     _eventSeverity =
61         entry.severity.value_or(convertOBMCSeverityToPEL(severity));
62 
63     // TODO: ibm-dev/dev/#1144 Handle manufacturing sev & action flags
64 
65     _eventType = entry.eventType.value_or(
66         static_cast<uint8_t>(EventType::notApplicable));
67 
68     _reserved4Byte1 = 0;
69 
70     // No uses for problem domain or vector
71     _problemDomain = 0;
72     _problemVector = 0;
73 
74     _actionFlags = entry.actionFlags.value_or(0);
75 
76     _reserved4Byte2 = 0;
77 
78     _valid = true;
79 }
80 
81 UserHeader::UserHeader(Stream& pel)
82 {
83     try
84     {
85         unflatten(pel);
86         validate();
87     }
88     catch (const std::exception& e)
89     {
90         log<level::ERR>("Cannot unflatten user header",
91                         entry("ERROR=%s", e.what()));
92         _valid = false;
93     }
94 }
95 
96 void UserHeader::validate()
97 {
98     bool failed = false;
99     if (header().id != static_cast<uint16_t>(SectionID::userHeader))
100     {
101         log<level::ERR>("Invalid user header section ID",
102                         entry("ID=0x%X", header().id));
103         failed = true;
104     }
105 
106     if (header().version != userHeaderVersion)
107     {
108         log<level::ERR>("Invalid user header version",
109                         entry("VERSION=0x%X", header().version));
110         failed = true;
111     }
112 
113     _valid = (failed) ? false : true;
114 }
115 
116 } // namespace pels
117 } // namespace openpower
118