1 #pragma once
2 
3 #include "pel_types.hpp"
4 #include "stream.hpp"
5 
6 #include <array>
7 #include <optional>
8 
9 namespace openpower
10 {
11 namespace pels
12 {
13 namespace src
14 {
15 
16 /**
17  * @brief Specifies if the incoming maintenance procedure or
18  *        symbolic FRU is the registry name or the raw name.
19  */
20 enum class CalloutValueType
21 {
22     raw,
23     registryName
24 };
25 
26 /**
27  * @class FRUIdentity
28  *
29  * This represents the FRU Identity substructure in the
30  * callout subsection of the SRC PEL section.
31  *
32  * It provides information about the FRU being called out,
33  * such as serial number and part number.  A maintenance
34  * procedure name may be used instead of the part number,
35  * and this would be indicated in the flags field.
36  */
37 class FRUIdentity
38 {
39   public:
40     /**
41      * @brief The failing component type
42      *
43      * Upper nibble of the flags byte
44      */
45     enum FailingComponentType
46     {
47         hardwareFRU = 0x10,
48         codeFRU = 0x20,
49         configError = 0x30,
50         maintenanceProc = 0x40,
51         externalFRU = 0x90,
52         externalCodeFRU = 0xA0,
53         toolFRU = 0xB0,
54         symbolicFRU = 0xC0,
55         symbolicFRUTrustedLocCode = 0xE0
56     };
57 
58     /**
59      * @brief The lower nibble of the flags byte
60      */
61     enum Flags
62     {
63         pnSupplied = 0x08,
64         ccinSupplied = 0x04,
65         maintProcSupplied = 0x02,
66         snSupplied = 0x01
67     };
68 
69     FRUIdentity() = delete;
70     ~FRUIdentity() = default;
71     FRUIdentity(const FRUIdentity&) = default;
72     FRUIdentity& operator=(const FRUIdentity&) = default;
73     FRUIdentity(FRUIdentity&&) = default;
74     FRUIdentity& operator=(FRUIdentity&&) = default;
75 
76     /**
77      * @brief Constructor
78      *
79      * Fills in this class's data fields from the stream.
80      *
81      * @param[in] pel - the PEL data stream
82      */
83     explicit FRUIdentity(Stream& pel);
84 
85     /**
86      * Constructor
87      *
88      * Creates the object as a hardware callout with the part number,
89      * CCIN, and serial number fields supplied.
90      *
91      * @param[in] partNumber - The part number of the FRU
92      * @param[in] ccin - The CCIN of the FRU
93      * @param[in] serialNumber - The serial number of the FRU
94      */
95     FRUIdentity(const std::string& partNumber, const std::string& ccin,
96                 const std::string& serialNumber);
97 
98     /**
99      * @brief Constructor
100      *
101      * Creates the object with a maintenance procedure callout.
102      *
103      * @param[in] procedureFromRegistry - The maintenance procedure name
104      *                                    as defined in the message registry.
105      */
106     FRUIdentity(const std::string& procedureFromRegistry) :
107         FRUIdentity(procedureFromRegistry, CalloutValueType::registryName)
108     {
109     }
110 
111     /**
112      * @brief Constructor
113      *
114      * Creates the object with a maintenance procedure callout.
115      *
116      * @param[in] procedure - The maintenance procedure name.
117      * @param[in] type - If the procedure is the raw name or the registry name.
118      */
119     FRUIdentity(const std::string& procedure, CalloutValueType type);
120 
121     /**
122      * @brief Constructor
123      *
124      * Creates the object with a symbolic FRU callout.
125      *
126      * @param[in] symbolicFRUFromRegistry - The symbolic FRU name as
127      *                                      defined in the message registry.
128      * @param[in] trustedLocationCode - If this FRU callout's location code
129      *                                  can be trusted to be correct.
130      */
131     FRUIdentity(const std::string& symbolicFRUFromRegistry,
132                 bool trustedLocationCode) :
133         FRUIdentity(symbolicFRUFromRegistry, CalloutValueType::registryName,
134                     trustedLocationCode)
135     {
136     }
137 
138     /**
139      * @brief Constructor
140      *
141      * Creates the object with a symbolic FRU callout.
142      *
143      * @param[in] fru - The symbolic FRU name.
144      * @param[in] type - If the FRU is the raw name or the registry name.
145      * @param[in] trustedLocationCode - If this FRU callout's location code
146      *                                  can be trusted to be correct.
147      */
148     FRUIdentity(const std::string& fru, CalloutValueType type,
149                 bool trustedLocationCode);
150 
151     /**
152      * @brief Flatten the object into the stream
153      *
154      * @param[in] stream - The stream to write to
155      */
156     void flatten(Stream& pel) const;
157 
158     /**
159      * @brief Returns the size of this structure when flattened into a PEL
160      *
161      * @return size_t - The size of the section
162      */
163     size_t flattenedSize() const;
164 
165     /**
166      * @brief Returns the type field
167      *
168      * @return uint16_t - The type, always 0x4944 "ID".
169      */
170     uint16_t type() const
171     {
172         return _type;
173     }
174     /**
175      * @brief The failing component type for this FRU callout.
176      *
177      * @return FailingComponentType
178      */
179     FailingComponentType failingComponentType() const
180     {
181         return static_cast<FailingComponentType>(_flags & 0xF0);
182     }
183 
184     /**
185      * @brief Returns the part number, if supplied
186      *
187      * @return std::optional<std::string>
188      */
189     std::optional<std::string> getPN() const;
190 
191     /**
192      * @brief Returns the maintenance procedure, if supplied
193      *
194      * @return std::optional<std::string>
195      */
196     std::optional<std::string> getMaintProc() const;
197 
198     /**
199      * @brief Returns the CCIN, if supplied
200      *
201      * @return std::optional<std::string>
202      */
203     std::optional<std::string> getCCIN() const;
204 
205     /**
206      * @brief Returns the serial number, if supplied
207      *
208      * @return std::optional<std::string>
209      */
210     std::optional<std::string> getSN() const;
211 
212     /**
213      * @brief The type identifier value of this structure.
214      */
215     static const uint16_t substructureType = 0x4944; // "ID"
216 
217   private:
218     /**
219      * @brief If the part number is contained in this structure.
220      *
221      * It takes the place of the maintenance procedure ID.
222      *
223      * @return bool
224      */
225     bool hasPN() const
226     {
227         return _flags & pnSupplied;
228     }
229 
230     /**
231      * @brief If the CCIN is contained in this structure.
232      *
233      * @return bool
234      */
235     bool hasCCIN() const
236     {
237         return _flags & ccinSupplied;
238     }
239 
240     /**
241      * @brief If a maintenance procedure is contained in this structure.
242      *
243      * It takes the place of the part number.
244      *
245      * @return bool
246      */
247     bool hasMP() const
248     {
249         return _flags & maintProcSupplied;
250     }
251 
252     /**
253      * @brief If the serial number is contained in this structure.
254      *
255      * @return bool
256      */
257     bool hasSN() const
258     {
259         return _flags & snSupplied;
260     }
261 
262     /**
263      * @brief Sets the 8 character null terminated part
264      *        number field to the string passed in.
265      *
266      * @param[in] partNumber - The part number string.
267      */
268     void setPartNumber(const std::string& partNumber);
269 
270     /**
271      * @brief Sets the 4 character CCIN field.
272      *
273      * @param[in] ccin - The CCIN string
274      */
275     void setCCIN(const std::string& ccin);
276 
277     /**
278      * @brief Sets the 12 character serial number field.
279      *
280      * @param[in] serialNumber - The serial number string
281      */
282     void setSerialNumber(const std::string& serialNumber);
283 
284     /**
285      * @brief Sets the 8 character null terminated procedure
286      *        field.  This is in the same field as the part
287      *        number since they are mutually exclusive.
288      *
289      * @param procedure - The procedure name.
290      * @param[in] type - If the procedure is the raw name or
291      *                   the registry name.
292      */
293     void setMaintenanceProcedure(const std::string& procedure,
294                                  CalloutValueType type);
295 
296     /**
297      * @brief Sets the 8 character null terminated symbolic FRU
298      *        field.  This is in the same field as the part
299      *        number since they are mutually exclusive.
300      *
301      * @param[in] symbolicFRU - The symbolic FRU name.
302      * @param[in] type - If the FRU is the raw name or
303      *                   the registry name.
304      */
305     void setSymbolicFRU(const std::string& symbolicFRU, CalloutValueType type);
306 
307     /**
308      * @brief The callout substructure type field. Will be "ID".
309      */
310     uint16_t _type;
311 
312     /**
313      * @brief The size of this callout structure.
314      *
315      * Always a multiple of 4.
316      */
317     uint8_t _size;
318 
319     /**
320      * @brief The flags byte of this substructure.
321      *
322      * See the FailingComponentType and Flags enums
323      */
324     uint8_t _flags;
325 
326     /**
327      * @brief The part number OR maintenance procedure ID,
328      *        depending on what the flags field specifies.
329      *
330      * A NULL terminated ASCII string.
331      */
332     std::array<char, 8> _pnOrProcedureID;
333 
334     /**
335      * @brief The CCIN VPD keyword
336      *
337      * Four ASCII characters, not NULL terminated.
338      */
339     std::array<char, 4> _ccin;
340 
341     /**
342      * @brief The serial number
343      *
344      * Twelve ASCII characters, not NULL terminated.
345      */
346     std::array<char, 12> _sn;
347 };
348 
349 } // namespace src
350 } // namespace pels
351 } // namespace openpower
352