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      */
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      */
85     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      */
101     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      */
118     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      */
128     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      */
138     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      */
148     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      * @return std::optional<std::string> - ExtendedUserHeader section's JSON
161      */
162     std::optional<std::string> getJSON() const override;
163 
164   private:
165     /**
166      * @brief Fills in the object from the stream data
167      *
168      * @param[in] stream - The stream to read from
169      */
170     void unflatten(Stream& stream);
171 
172     /**
173      * @brief Validates the section contents
174      *
175      * Updates _valid (in Section) with the results.
176      */
177     void validate() override;
178 
179     /**
180      * @brief Builds the symptom ID
181      *
182      * Uses the message registry to say which SRC fields to add
183      * to the SRC's ASCII string to make the ID, and uses a smart
184      * default if not specified in the registry.
185      *
186      * @param[in] regEntry - The message registry entry for this event
187      * @param[in] src - The SRC section object for this event
188      */
189     void createSymptomID(const message::Entry& regEntry, const SRC& src);
190 
191     /**
192      * @brief The structure that holds the machine TM and SN fields.
193      */
194     MTMS _mtms;
195 
196     /**
197      * @brief The server firmware version
198      *
199      * NULL terminated.
200      *
201      * The release version of the full firmware image.
202      */
203     std::array<uint8_t, firmwareVersionSize> _serverFWVersion;
204 
205     /**
206      * @brief The subsystem firmware version
207      *
208      * NULL terminated.
209      *
210      * On PELs created on the BMC, this will be the BMC code version.
211      */
212     std::array<uint8_t, firmwareVersionSize> _subsystemFWVersion;
213 
214     /**
215      * @brief Reserved
216      */
217     uint32_t _reserved4B = 0;
218 
219     /**
220      * @brief Event Common Reference Time
221      *
222      * This is not used by PELs created on the BMC.
223      */
224     BCDTime _refTime;
225 
226     /**
227      * @brief Reserved
228      */
229     uint8_t _reserved1B1 = 0;
230 
231     /**
232      * @brief Reserved
233      */
234     uint8_t _reserved1B2 = 0;
235 
236     /**
237      * @brief Reserved
238      */
239     uint8_t _reserved1B3 = 0;
240 
241     /**
242      * @brief The size of the symptom ID field
243      */
244     uint8_t _symptomIDSize;
245 
246     /**
247      * @brief The symptom ID field
248      *
249      * Describes a unique event signature for the log.
250      * Required for serviceable events, otherwise optional.
251      * When present, must start with the first 8 characters
252      * of the ASCII string field from the SRC.
253      *
254      * NULL terminated.
255      */
256     std::vector<uint8_t> _symptomID;
257 };
258 
259 } // namespace pels
260 } // namespace openpower
261