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