1 #pragma once
2 
3 #include "bcd_time.hpp"
4 #include "data_interface.hpp"
5 #include "elog_entry.hpp"
6 #include "mtms.hpp"
7 #include "registry.hpp"
8 #include "section.hpp"
9 #include "src.hpp"
10 #include "stream.hpp"
11 
12 namespace openpower
13 {
14 namespace pels
15 {
16 
17 constexpr uint8_t extendedUserHeaderVersion = 0x01;
18 constexpr size_t firmwareVersionSize = 16;
19 
20 /**
21  * @class ExtendedUserHeader
22  *
23  * This represents the Extended User Header section in a PEL.  It is  a required
24  * section.  It contains code versions, an MTMS subsection, and a string called
25  * a symptom ID.
26  *
27  * The Section base class handles the section header structure that every
28  * PEL section has at offset zero.
29  */
30 class ExtendedUserHeader : public Section
31 {
32   public:
33     ExtendedUserHeader() = delete;
34     ~ExtendedUserHeader() = default;
35     ExtendedUserHeader(const ExtendedUserHeader&) = default;
36     ExtendedUserHeader& operator=(const ExtendedUserHeader&) = default;
37     ExtendedUserHeader(ExtendedUserHeader&&) = default;
38     ExtendedUserHeader& operator=(ExtendedUserHeader&&) = default;
39 
40     /**
41      * @brief Constructor
42      *
43      * Fills in this class's data fields from the stream.
44      *
45      * @param[in] pel - the PEL data stream
46      */
47     explicit ExtendedUserHeader(Stream& pel);
48 
49     /**
50      * @brief Constructor
51      *
52      * @param[in] dataIface - The DataInterface object
53      * @param[in] regEntry - The message registry entry for this event
54      * @param[in] src - The SRC section object for this event
55      */
56     ExtendedUserHeader(const DataInterfaceBase& dataIface,
57                        const message::Entry& regEntry, const SRC& src);
58 
59     /**
60      * @brief Flatten the section into the stream
61      *
62      * @param[in] stream - The stream to write to
63      */
64     void flatten(Stream& stream) const override;
65 
66     /**
67      * @brief Returns the size of this section when flattened into a PEL
68      *
69      * @return size_t - the size of the section
70      */
flattenedSize()71     size_t flattenedSize()
72     {
73         return Section::flattenedSize() + _mtms.flattenedSize() +
74                _serverFWVersion.size() + _subsystemFWVersion.size() +
75                sizeof(_reserved4B) + sizeof(_refTime) + sizeof(_reserved1B1) +
76                sizeof(_reserved1B2) + sizeof(_reserved1B3) +
77                sizeof(_symptomIDSize) + _symptomIDSize;
78     }
79 
80     /**
81      * @brief Returns the server firmware version
82      *
83      * @return std::string - The version
84      */
serverFWVersion() const85     std::string serverFWVersion() const
86     {
87         std::string version;
88         for (size_t i = 0;
89              i < _serverFWVersion.size() && _serverFWVersion[i] != '\0'; i++)
90         {
91             version.push_back(_serverFWVersion[i]);
92         }
93         return version;
94     }
95 
96     /**
97      * @brief Returns the subsystem firmware version
98      *
99      * @return std::string - The version
100      */
subsystemFWVersion() const101     std::string subsystemFWVersion() const
102     {
103         std::string version;
104         for (size_t i = 0;
105              i < _subsystemFWVersion.size() && _subsystemFWVersion[i] != '\0';
106              i++)
107         {
108             version.push_back(_subsystemFWVersion[i]);
109         }
110         return version;
111     }
112 
113     /**
114      * @brief Returns the machine type+model
115      *
116      * @return std::string - The MTM
117      */
machineTypeModel() const118     std::string machineTypeModel() const
119     {
120         return _mtms.machineTypeAndModel();
121     }
122 
123     /**
124      * @brief Returns the machine serial number
125      *
126      * @return std::string - The serial number
127      */
machineSerialNumber() const128     std::string machineSerialNumber() const
129     {
130         return _mtms.machineSerialNumber();
131     }
132 
133     /**
134      * @brief Returns the Event Common Reference Time field
135      *
136      * @return BCDTime - The time value
137      */
refTime() const138     const BCDTime& refTime() const
139     {
140         return _refTime;
141     }
142 
143     /**
144      * @brief Returns the symptom ID
145      *
146      * @return std::string - The symptom ID
147      */
symptomID() const148     std::string symptomID() const
149     {
150         std::string symptom;
151         for (size_t i = 0; i < _symptomID.size() && _symptomID[i] != '\0'; i++)
152         {
153             symptom.push_back(_symptomID[i]);
154         }
155         return symptom;
156     }
157 
158     /**
159      * @brief Get section in JSON.
160      *
161      * @param[in] creatorID - The creator ID for the PEL
162      *
163      * @return std::optional<std::string> - ExtendedUserHeader section's JSON
164      */
165     std::optional<std::string> getJSON(uint8_t creatorID) const override;
166 
167   private:
168     /**
169      * @brief Fills in the object from the stream data
170      *
171      * @param[in] stream - The stream to read from
172      */
173     void unflatten(Stream& stream);
174 
175     /**
176      * @brief Validates the section contents
177      *
178      * Updates _valid (in Section) with the results.
179      */
180     void validate() override;
181 
182     /**
183      * @brief Builds the symptom ID
184      *
185      * Uses the message registry to say which SRC fields to add
186      * to the SRC's ASCII string to make the ID, and uses a smart
187      * default if not specified in the registry.
188      *
189      * @param[in] regEntry - The message registry entry for this event
190      * @param[in] src - The SRC section object for this event
191      */
192     void createSymptomID(const message::Entry& regEntry, const SRC& src);
193 
194     /**
195      * @brief The structure that holds the machine TM and SN fields.
196      */
197     MTMS _mtms;
198 
199     /**
200      * @brief The server firmware version
201      *
202      * NULL terminated.
203      *
204      * The release version of the full firmware image.
205      */
206     std::array<uint8_t, firmwareVersionSize> _serverFWVersion;
207 
208     /**
209      * @brief The subsystem firmware version
210      *
211      * NULL terminated.
212      *
213      * On PELs created on the BMC, this will be the BMC code version.
214      */
215     std::array<uint8_t, firmwareVersionSize> _subsystemFWVersion;
216 
217     /**
218      * @brief Reserved
219      */
220     uint32_t _reserved4B = 0;
221 
222     /**
223      * @brief Event Common Reference Time
224      *
225      * This is not used by PELs created on the BMC.
226      */
227     BCDTime _refTime;
228 
229     /**
230      * @brief Reserved
231      */
232     uint8_t _reserved1B1 = 0;
233 
234     /**
235      * @brief Reserved
236      */
237     uint8_t _reserved1B2 = 0;
238 
239     /**
240      * @brief Reserved
241      */
242     uint8_t _reserved1B3 = 0;
243 
244     /**
245      * @brief The size of the symptom ID field
246      */
247     uint8_t _symptomIDSize;
248 
249     /**
250      * @brief The symptom ID field
251      *
252      * Describes a unique event signature for the log.
253      * Required for serviceable events, otherwise optional.
254      * When present, must start with the first 8 characters
255      * of the ASCII string field from the SRC.
256      *
257      * NULL terminated.
258      */
259     std::vector<uint8_t> _symptomID;
260 };
261 
262 } // namespace pels
263 } // namespace openpower
264