1cb6b059eSMatt Spinler #pragma once
2cb6b059eSMatt Spinler 
3b832363dSMatt Spinler #include "additional_data.hpp"
4*aa659477SMatt Spinler #include "data_interface.hpp"
5cb6b059eSMatt Spinler #include "private_header.hpp"
6b832363dSMatt Spinler #include "registry.hpp"
7bd716f00SMatt Spinler #include "src.hpp"
8cb6b059eSMatt Spinler #include "user_header.hpp"
9cb6b059eSMatt Spinler 
10cb6b059eSMatt Spinler #include <memory>
11cb6b059eSMatt Spinler #include <vector>
12cb6b059eSMatt Spinler 
13cb6b059eSMatt Spinler namespace openpower
14cb6b059eSMatt Spinler {
15cb6b059eSMatt Spinler namespace pels
16cb6b059eSMatt Spinler {
17cb6b059eSMatt Spinler 
18cb6b059eSMatt Spinler /** @class PEL
19cb6b059eSMatt Spinler  *
20cb6b059eSMatt Spinler  * @brief This class represents a specific event log format referred to as a
21cb6b059eSMatt Spinler  * Platform Event Log.
22cb6b059eSMatt Spinler  *
23cb6b059eSMatt Spinler  * Every field in a PEL are in structures call sections, of which there are
24cb6b059eSMatt Spinler  * several types.  Some sections are required, and some are optional.  In some
25cb6b059eSMatt Spinler  * cases there may be more than one instance of a section type.
26cb6b059eSMatt Spinler  *
27cb6b059eSMatt Spinler  * The only two required sections for every type of PEL are the Private Header
28cb6b059eSMatt Spinler  * section and User Header section, which must be in the first and second
29cb6b059eSMatt Spinler  * positions, respectively.
30cb6b059eSMatt Spinler  *
31cb6b059eSMatt Spinler  * Every section starts with an 8 byte section header, which has the section
32cb6b059eSMatt Spinler  * size and type, among other things.
33cb6b059eSMatt Spinler  *
34cb6b059eSMatt Spinler  * This class represents all sections with objects.
35cb6b059eSMatt Spinler  *
36bd716f00SMatt Spinler  * The class can be constructed:
37bd716f00SMatt Spinler  * - From a full formed flattened PEL.
38bd716f00SMatt Spinler  * - From scratch based on an OpenBMC event and its corresponding PEL message
39bd716f00SMatt Spinler  *   registry entry.
40b832363dSMatt Spinler  *
41cb6b059eSMatt Spinler  * The data() method allows one to retrieve the PEL as a vector<uint8_t>.  This
42cb6b059eSMatt Spinler  * is the format in which it is stored and transmitted.
43cb6b059eSMatt Spinler  */
44cb6b059eSMatt Spinler class PEL
45cb6b059eSMatt Spinler {
46cb6b059eSMatt Spinler   public:
47cb6b059eSMatt Spinler     PEL() = delete;
48cb6b059eSMatt Spinler     ~PEL() = default;
49cb6b059eSMatt Spinler     PEL(const PEL&) = delete;
50cb6b059eSMatt Spinler     PEL& operator=(const PEL&) = delete;
51cb6b059eSMatt Spinler     PEL(PEL&&) = delete;
52cb6b059eSMatt Spinler     PEL& operator=(PEL&&) = delete;
53cb6b059eSMatt Spinler 
54cb6b059eSMatt Spinler     /**
55cb6b059eSMatt Spinler      * @brief Constructor
56cb6b059eSMatt Spinler      *
57cb6b059eSMatt Spinler      * Build a PEL from raw data.
58cb6b059eSMatt Spinler      *
5907eefc54SMatt Spinler      * Note: Neither this nor the following constructor can take a const vector&
6007eefc54SMatt Spinler      * because the Stream class that is used to read from the vector cannot take
6107eefc54SMatt Spinler      * a const.  The alternative is to make a copy of the data, but as PELs can
6207eefc54SMatt Spinler      * be up to 16KB that is undesireable.
6307eefc54SMatt Spinler      *
64cb6b059eSMatt Spinler      * @param[in] data - The PEL data
65cb6b059eSMatt Spinler      */
6607eefc54SMatt Spinler     PEL(std::vector<uint8_t>& data);
67cb6b059eSMatt Spinler 
68cb6b059eSMatt Spinler     /**
69cb6b059eSMatt Spinler      * @brief Constructor
70cb6b059eSMatt Spinler      *
71cb6b059eSMatt Spinler      * Build a PEL from the raw data.
72cb6b059eSMatt Spinler      *
73cb6b059eSMatt Spinler      * @param[in] data - the PEL data
74cb6b059eSMatt Spinler      * @param[in] obmcLogID - the corresponding OpenBMC event log ID
75cb6b059eSMatt Spinler      */
7607eefc54SMatt Spinler     PEL(std::vector<uint8_t>& data, uint32_t obmcLogID);
77cb6b059eSMatt Spinler 
78cb6b059eSMatt Spinler     /**
79b832363dSMatt Spinler      * @brief Constructor
80b832363dSMatt Spinler      *
81b832363dSMatt Spinler      * Creates a PEL from an OpenBMC event log and its message
82b832363dSMatt Spinler      * registry entry.
83b832363dSMatt Spinler      *
84b832363dSMatt Spinler      * @param[in] entry - The message registry entry for this error
85b832363dSMatt Spinler      * @param[in] obmcLogID - ID of corresponding OpenBMC event log
86b832363dSMatt Spinler      * @param[in] timestamp - Timestamp from the event log
87b832363dSMatt Spinler      * @param[in] severity - Severity from the event log
88bd716f00SMatt Spinler      * @param[in] additionalData - The AdditionalData contents
89*aa659477SMatt Spinler      * @param[in] dataIface - The data interface object
90b832363dSMatt Spinler      */
91b832363dSMatt Spinler     PEL(const openpower::pels::message::Entry& entry, uint32_t obmcLogID,
92bd716f00SMatt Spinler         uint64_t timestamp, phosphor::logging::Entry::Level severity,
93*aa659477SMatt Spinler         const AdditionalData& additionalData,
94*aa659477SMatt Spinler         const DataInterfaceBase& dataIface);
95b832363dSMatt Spinler 
96b832363dSMatt Spinler     /**
97cb6b059eSMatt Spinler      * @brief Convenience function to return the log ID field from the
98cb6b059eSMatt Spinler      *        Private Header section.
99cb6b059eSMatt Spinler      *
100cb6b059eSMatt Spinler      * @return uint32_t - the ID
101cb6b059eSMatt Spinler      */
102cb6b059eSMatt Spinler     uint32_t id() const
103cb6b059eSMatt Spinler     {
104cb6b059eSMatt Spinler         return _ph->id();
105cb6b059eSMatt Spinler     }
106cb6b059eSMatt Spinler 
107cb6b059eSMatt Spinler     /**
108cb6b059eSMatt Spinler      * @brief Convenience function to return the PLID field from the
109cb6b059eSMatt Spinler      *        Private Header section.
110cb6b059eSMatt Spinler      *
111cb6b059eSMatt Spinler      * @return uint32_t - the PLID
112cb6b059eSMatt Spinler      */
113cb6b059eSMatt Spinler     uint32_t plid() const
114cb6b059eSMatt Spinler     {
115cb6b059eSMatt Spinler         return _ph->plid();
116cb6b059eSMatt Spinler     }
117cb6b059eSMatt Spinler 
118cb6b059eSMatt Spinler     /**
119cb6b059eSMatt Spinler      * @brief Convenience function to return the OpenBMC event log ID field
120cb6b059eSMatt Spinler      * from the Private Header section.
121cb6b059eSMatt Spinler      *
122cb6b059eSMatt Spinler      * @return uint32_t - the OpenBMC event log ID
123cb6b059eSMatt Spinler      */
124cb6b059eSMatt Spinler     uint32_t obmcLogID() const
125cb6b059eSMatt Spinler     {
126cb6b059eSMatt Spinler         return _ph->obmcLogID();
127cb6b059eSMatt Spinler     }
128cb6b059eSMatt Spinler 
129cb6b059eSMatt Spinler     /**
130cb6b059eSMatt Spinler      * @brief Convenience function to return the commit time field from
131cb6b059eSMatt Spinler      *        the Private Header section.
132cb6b059eSMatt Spinler      *
133cb6b059eSMatt Spinler      * @return BCDTime - the timestamp
134cb6b059eSMatt Spinler      */
135cb6b059eSMatt Spinler     BCDTime commitTime() const
136cb6b059eSMatt Spinler     {
137cb6b059eSMatt Spinler         return _ph->commitTimestamp();
138cb6b059eSMatt Spinler     }
139cb6b059eSMatt Spinler 
140cb6b059eSMatt Spinler     /**
141cb6b059eSMatt Spinler      * @brief Convenience function to return the create time field from
142cb6b059eSMatt Spinler      *        the Private Header section.
143cb6b059eSMatt Spinler      *
144cb6b059eSMatt Spinler      * @return BCDTime - the timestamp
145cb6b059eSMatt Spinler      */
146cb6b059eSMatt Spinler     BCDTime createTime() const
147cb6b059eSMatt Spinler     {
148cb6b059eSMatt Spinler         return _ph->createTimestamp();
149cb6b059eSMatt Spinler     }
150cb6b059eSMatt Spinler 
151cb6b059eSMatt Spinler     /**
152cb6b059eSMatt Spinler      * @brief Gives access to the Private Header section class
153cb6b059eSMatt Spinler      *
154cb6b059eSMatt Spinler      * @return std::unique_ptr<PrivateHeader>& the private header
155cb6b059eSMatt Spinler      */
156cb6b059eSMatt Spinler     std::unique_ptr<PrivateHeader>& privateHeader()
157cb6b059eSMatt Spinler     {
158cb6b059eSMatt Spinler         return _ph;
159cb6b059eSMatt Spinler     }
160cb6b059eSMatt Spinler 
161cb6b059eSMatt Spinler     /**
162cb6b059eSMatt Spinler      * @brief Gives access to the User Header section class
163cb6b059eSMatt Spinler      *
164cb6b059eSMatt Spinler      * @return std::unique_ptr<UserHeader>& the user header
165cb6b059eSMatt Spinler      */
166cb6b059eSMatt Spinler     std::unique_ptr<UserHeader>& userHeader()
167cb6b059eSMatt Spinler     {
168cb6b059eSMatt Spinler         return _uh;
169cb6b059eSMatt Spinler     }
170cb6b059eSMatt Spinler 
171cb6b059eSMatt Spinler     /**
172bd716f00SMatt Spinler      * @brief Gives access to the primary SRC's section class
173bd716f00SMatt Spinler      *
174bd716f00SMatt Spinler      * This is technically an optional section, so the return
175bd716f00SMatt Spinler      * value is an std::optional<SRC*>.
176bd716f00SMatt Spinler      *
177bd716f00SMatt Spinler      * @return std::optional<SRC*> - the SRC section object
178bd716f00SMatt Spinler      */
179bd716f00SMatt Spinler     std::optional<SRC*> primarySRC() const;
180bd716f00SMatt Spinler 
181bd716f00SMatt Spinler     /**
182131870c7SMatt Spinler      * @brief Returns the optional sections, which is everything but
183131870c7SMatt Spinler      *        the Private and User Headers.
184131870c7SMatt Spinler      *
185131870c7SMatt Spinler      * @return const std::vector<std::unique_ptr<Section>>&
186131870c7SMatt Spinler      */
187131870c7SMatt Spinler     const std::vector<std::unique_ptr<Section>>& optionalSections() const
188131870c7SMatt Spinler     {
189131870c7SMatt Spinler         return _optionalSections;
190131870c7SMatt Spinler     }
191131870c7SMatt Spinler 
192131870c7SMatt Spinler     /**
193cb6b059eSMatt Spinler      * @brief Returns the PEL data.
194cb6b059eSMatt Spinler      *
195cb6b059eSMatt Spinler      * @return std::vector<uint8_t> - the raw PEL data
196cb6b059eSMatt Spinler      */
197cb6b059eSMatt Spinler     std::vector<uint8_t> data();
198cb6b059eSMatt Spinler 
199cb6b059eSMatt Spinler     /**
200cb6b059eSMatt Spinler      * @brief Says if the PEL is valid (the sections are all valid)
201cb6b059eSMatt Spinler      *
202cb6b059eSMatt Spinler      * @return bool - if the PEL is valid
203cb6b059eSMatt Spinler      */
204cb6b059eSMatt Spinler     bool valid() const;
205cb6b059eSMatt Spinler 
206cb6b059eSMatt Spinler     /**
207cb6b059eSMatt Spinler      * @brief Sets the commit timestamp to the current time
208cb6b059eSMatt Spinler      */
209cb6b059eSMatt Spinler     void setCommitTime();
210cb6b059eSMatt Spinler 
211cb6b059eSMatt Spinler     /**
212cb6b059eSMatt Spinler      * @brief Sets the error log ID field to a unique ID.
213cb6b059eSMatt Spinler      */
214cb6b059eSMatt Spinler     void assignID();
215cb6b059eSMatt Spinler 
216cb6b059eSMatt Spinler   private:
217cb6b059eSMatt Spinler     /**
218cb6b059eSMatt Spinler      * @brief Builds the section objects from a PEL data buffer
219cb6b059eSMatt Spinler      *
22007eefc54SMatt Spinler      * Note: The data parameter cannot be const for the same reasons
22107eefc54SMatt Spinler      * as listed in the constructor.
22207eefc54SMatt Spinler      *
22307eefc54SMatt Spinler      * @param[in] data - The PEL data
224cb6b059eSMatt Spinler      * @param[in] obmcLogID - The OpenBMC event log ID to use for that
225cb6b059eSMatt Spinler      *                        field in the Private Header.
226cb6b059eSMatt Spinler      */
22707eefc54SMatt Spinler     void populateFromRawData(std::vector<uint8_t>& data, uint32_t obmcLogID);
228cb6b059eSMatt Spinler 
229cb6b059eSMatt Spinler     /**
230cb6b059eSMatt Spinler      * @brief Flattens the PEL objects into the buffer
231cb6b059eSMatt Spinler      *
232cb6b059eSMatt Spinler      * @param[out] pelBuffer - What the data will be written to
233cb6b059eSMatt Spinler      */
234cb6b059eSMatt Spinler     void flatten(std::vector<uint8_t>& pelBuffer);
235cb6b059eSMatt Spinler 
236cb6b059eSMatt Spinler     /**
237cb6b059eSMatt Spinler      * @brief The PEL Private Header section
238cb6b059eSMatt Spinler      */
239cb6b059eSMatt Spinler     std::unique_ptr<PrivateHeader> _ph;
240cb6b059eSMatt Spinler 
241cb6b059eSMatt Spinler     /**
242cb6b059eSMatt Spinler      * @brief The PEL User Header section
243cb6b059eSMatt Spinler      */
244cb6b059eSMatt Spinler     std::unique_ptr<UserHeader> _uh;
245cb6b059eSMatt Spinler 
246cb6b059eSMatt Spinler     /**
247131870c7SMatt Spinler      * @brief Holds all sections by the PH and UH.
248131870c7SMatt Spinler      */
249131870c7SMatt Spinler     std::vector<std::unique_ptr<Section>> _optionalSections;
250cb6b059eSMatt Spinler };
251cb6b059eSMatt Spinler 
252cb6b059eSMatt Spinler } // namespace pels
253cb6b059eSMatt Spinler } // namespace openpower
254