blob: 9f34b623b933aeb129a4c41c42db44fe706b8bd8 [file] [log] [blame]
Matt Spinlercb6b0592019-07-16 15:58:51 -05001#pragma once
2
Matt Spinlerb8323632019-09-20 15:11:04 -05003#include "additional_data.hpp"
Matt Spinlercb6b0592019-07-16 15:58:51 -05004#include "private_header.hpp"
Matt Spinlerb8323632019-09-20 15:11:04 -05005#include "registry.hpp"
Matt Spinlerbd716f02019-10-15 10:54:11 -05006#include "src.hpp"
Matt Spinlercb6b0592019-07-16 15:58:51 -05007#include "user_header.hpp"
8
9#include <memory>
10#include <vector>
11
12namespace openpower
13{
14namespace pels
15{
16
17/** @class PEL
18 *
19 * @brief This class represents a specific event log format referred to as a
20 * Platform Event Log.
21 *
22 * Every field in a PEL are in structures call sections, of which there are
23 * several types. Some sections are required, and some are optional. In some
24 * cases there may be more than one instance of a section type.
25 *
26 * The only two required sections for every type of PEL are the Private Header
27 * section and User Header section, which must be in the first and second
28 * positions, respectively.
29 *
30 * Every section starts with an 8 byte section header, which has the section
31 * size and type, among other things.
32 *
33 * This class represents all sections with objects.
34 *
Matt Spinlerbd716f02019-10-15 10:54:11 -050035 * The class can be constructed:
36 * - From a full formed flattened PEL.
37 * - From scratch based on an OpenBMC event and its corresponding PEL message
38 * registry entry.
Matt Spinlerb8323632019-09-20 15:11:04 -050039 *
Matt Spinlercb6b0592019-07-16 15:58:51 -050040 * The data() method allows one to retrieve the PEL as a vector<uint8_t>. This
41 * is the format in which it is stored and transmitted.
42 */
43class PEL
44{
45 public:
46 PEL() = delete;
47 ~PEL() = default;
48 PEL(const PEL&) = delete;
49 PEL& operator=(const PEL&) = delete;
50 PEL(PEL&&) = delete;
51 PEL& operator=(PEL&&) = delete;
52
53 /**
54 * @brief Constructor
55 *
56 * Build a PEL from raw data.
57 *
Matt Spinler07eefc52019-09-26 11:18:26 -050058 * Note: Neither this nor the following constructor can take a const vector&
59 * because the Stream class that is used to read from the vector cannot take
60 * a const. The alternative is to make a copy of the data, but as PELs can
61 * be up to 16KB that is undesireable.
62 *
Matt Spinlercb6b0592019-07-16 15:58:51 -050063 * @param[in] data - The PEL data
64 */
Matt Spinler07eefc52019-09-26 11:18:26 -050065 PEL(std::vector<uint8_t>& data);
Matt Spinlercb6b0592019-07-16 15:58:51 -050066
67 /**
68 * @brief Constructor
69 *
70 * Build a PEL from the raw data.
71 *
72 * @param[in] data - the PEL data
73 * @param[in] obmcLogID - the corresponding OpenBMC event log ID
74 */
Matt Spinler07eefc52019-09-26 11:18:26 -050075 PEL(std::vector<uint8_t>& data, uint32_t obmcLogID);
Matt Spinlercb6b0592019-07-16 15:58:51 -050076
77 /**
Matt Spinlerb8323632019-09-20 15:11:04 -050078 * @brief Constructor
79 *
80 * Creates a PEL from an OpenBMC event log and its message
81 * registry entry.
82 *
83 * @param[in] entry - The message registry entry for this error
84 * @param[in] obmcLogID - ID of corresponding OpenBMC event log
85 * @param[in] timestamp - Timestamp from the event log
86 * @param[in] severity - Severity from the event log
Matt Spinlerbd716f02019-10-15 10:54:11 -050087 * @param[in] additionalData - The AdditionalData contents
Matt Spinlerb8323632019-09-20 15:11:04 -050088 */
89 PEL(const openpower::pels::message::Entry& entry, uint32_t obmcLogID,
Matt Spinlerbd716f02019-10-15 10:54:11 -050090 uint64_t timestamp, phosphor::logging::Entry::Level severity,
91 const AdditionalData& additionalData);
Matt Spinlerb8323632019-09-20 15:11:04 -050092
93 /**
Matt Spinlercb6b0592019-07-16 15:58:51 -050094 * @brief Convenience function to return the log ID field from the
95 * Private Header section.
96 *
97 * @return uint32_t - the ID
98 */
99 uint32_t id() const
100 {
101 return _ph->id();
102 }
103
104 /**
105 * @brief Convenience function to return the PLID field from the
106 * Private Header section.
107 *
108 * @return uint32_t - the PLID
109 */
110 uint32_t plid() const
111 {
112 return _ph->plid();
113 }
114
115 /**
116 * @brief Convenience function to return the OpenBMC event log ID field
117 * from the Private Header section.
118 *
119 * @return uint32_t - the OpenBMC event log ID
120 */
121 uint32_t obmcLogID() const
122 {
123 return _ph->obmcLogID();
124 }
125
126 /**
127 * @brief Convenience function to return the commit time field from
128 * the Private Header section.
129 *
130 * @return BCDTime - the timestamp
131 */
132 BCDTime commitTime() const
133 {
134 return _ph->commitTimestamp();
135 }
136
137 /**
138 * @brief Convenience function to return the create time field from
139 * the Private Header section.
140 *
141 * @return BCDTime - the timestamp
142 */
143 BCDTime createTime() const
144 {
145 return _ph->createTimestamp();
146 }
147
148 /**
149 * @brief Gives access to the Private Header section class
150 *
151 * @return std::unique_ptr<PrivateHeader>& the private header
152 */
153 std::unique_ptr<PrivateHeader>& privateHeader()
154 {
155 return _ph;
156 }
157
158 /**
159 * @brief Gives access to the User Header section class
160 *
161 * @return std::unique_ptr<UserHeader>& the user header
162 */
163 std::unique_ptr<UserHeader>& userHeader()
164 {
165 return _uh;
166 }
167
168 /**
Matt Spinlerbd716f02019-10-15 10:54:11 -0500169 * @brief Gives access to the primary SRC's section class
170 *
171 * This is technically an optional section, so the return
172 * value is an std::optional<SRC*>.
173 *
174 * @return std::optional<SRC*> - the SRC section object
175 */
176 std::optional<SRC*> primarySRC() const;
177
178 /**
Matt Spinler131870c2019-09-25 13:29:04 -0500179 * @brief Returns the optional sections, which is everything but
180 * the Private and User Headers.
181 *
182 * @return const std::vector<std::unique_ptr<Section>>&
183 */
184 const std::vector<std::unique_ptr<Section>>& optionalSections() const
185 {
186 return _optionalSections;
187 }
188
189 /**
Matt Spinlercb6b0592019-07-16 15:58:51 -0500190 * @brief Returns the PEL data.
191 *
192 * @return std::vector<uint8_t> - the raw PEL data
193 */
194 std::vector<uint8_t> data();
195
196 /**
197 * @brief Says if the PEL is valid (the sections are all valid)
198 *
199 * @return bool - if the PEL is valid
200 */
201 bool valid() const;
202
203 /**
204 * @brief Sets the commit timestamp to the current time
205 */
206 void setCommitTime();
207
208 /**
209 * @brief Sets the error log ID field to a unique ID.
210 */
211 void assignID();
212
213 private:
214 /**
215 * @brief Builds the section objects from a PEL data buffer
216 *
Matt Spinler07eefc52019-09-26 11:18:26 -0500217 * Note: The data parameter cannot be const for the same reasons
218 * as listed in the constructor.
219 *
220 * @param[in] data - The PEL data
Matt Spinlercb6b0592019-07-16 15:58:51 -0500221 * @param[in] obmcLogID - The OpenBMC event log ID to use for that
222 * field in the Private Header.
223 */
Matt Spinler07eefc52019-09-26 11:18:26 -0500224 void populateFromRawData(std::vector<uint8_t>& data, uint32_t obmcLogID);
Matt Spinlercb6b0592019-07-16 15:58:51 -0500225
226 /**
227 * @brief Flattens the PEL objects into the buffer
228 *
229 * @param[out] pelBuffer - What the data will be written to
230 */
231 void flatten(std::vector<uint8_t>& pelBuffer);
232
233 /**
234 * @brief The PEL Private Header section
235 */
236 std::unique_ptr<PrivateHeader> _ph;
237
238 /**
239 * @brief The PEL User Header section
240 */
241 std::unique_ptr<UserHeader> _uh;
242
243 /**
Matt Spinler131870c2019-09-25 13:29:04 -0500244 * @brief Holds all sections by the PH and UH.
245 */
246 std::vector<std::unique_ptr<Section>> _optionalSections;
Matt Spinlercb6b0592019-07-16 15:58:51 -0500247};
248
249} // namespace pels
250} // namespace openpower