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      */
FRUIdentity(const std::string & procedureFromRegistry)106     explicit FRUIdentity(const std::string& procedureFromRegistry) :
107         FRUIdentity(procedureFromRegistry, CalloutValueType::registryName)
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      */
FRUIdentity(const std::string & symbolicFRUFromRegistry,bool trustedLocationCode)130     FRUIdentity(const std::string& symbolicFRUFromRegistry,
131                 bool trustedLocationCode) :
132         FRUIdentity(symbolicFRUFromRegistry, CalloutValueType::registryName,
133                     trustedLocationCode)
134     {}
135 
136     /**
137      * @brief Constructor
138      *
139      * Creates the object with a symbolic FRU callout.
140      *
141      * @param[in] fru - The symbolic FRU name.
142      * @param[in] type - If the FRU is the raw name or the registry name.
143      * @param[in] trustedLocationCode - If this FRU callout's location code
144      *                                  can be trusted to be correct.
145      */
146     FRUIdentity(const std::string& fru, CalloutValueType type,
147                 bool trustedLocationCode);
148 
149     /**
150      * @brief Flatten the object into the stream
151      *
152      * @param[in] stream - The stream to write to
153      */
154     void flatten(Stream& pel) const;
155 
156     /**
157      * @brief Returns the size of this structure when flattened into a PEL
158      *
159      * @return size_t - The size of the section
160      */
161     size_t flattenedSize() const;
162 
163     /**
164      * @brief Returns the type field
165      *
166      * @return uint16_t - The type, always 0x4944 "ID".
167      */
type() const168     uint16_t type() const
169     {
170         return _type;
171     }
172     /**
173      * @brief The failing component type for this FRU callout.
174      *
175      * @return FailingComponentType
176      */
failingComponentType() const177     FailingComponentType failingComponentType() const
178     {
179         return static_cast<FailingComponentType>(_flags & 0xF0);
180     }
181 
182     /**
183      * @brief Returns the part number, if supplied
184      *
185      * @return std::optional<std::string>
186      */
187     std::optional<std::string> getPN() const;
188 
189     /**
190      * @brief Returns the maintenance procedure, if supplied
191      *
192      * @return std::optional<std::string>
193      */
194     std::optional<std::string> getMaintProc() const;
195 
196     /**
197      * @brief Returns the CCIN, if supplied
198      *
199      * @return std::optional<std::string>
200      */
201     std::optional<std::string> getCCIN() const;
202 
203     /**
204      * @brief Returns the serial number, if supplied
205      *
206      * @return std::optional<std::string>
207      */
208     std::optional<std::string> getSN() const;
209 
210     /**
211      * @brief The type identifier value of this structure.
212      */
213     static const uint16_t substructureType = 0x4944; // "ID"
214 
215   private:
216     /**
217      * @brief If the part number is contained in this structure.
218      *
219      * It takes the place of the maintenance procedure ID.
220      *
221      * @return bool
222      */
hasPN() const223     bool hasPN() const
224     {
225         return _flags & pnSupplied;
226     }
227 
228     /**
229      * @brief If the CCIN is contained in this structure.
230      *
231      * @return bool
232      */
hasCCIN() const233     bool hasCCIN() const
234     {
235         return _flags & ccinSupplied;
236     }
237 
238     /**
239      * @brief If a maintenance procedure is contained in this structure.
240      *
241      * It takes the place of the part number.
242      *
243      * @return bool
244      */
hasMP() const245     bool hasMP() const
246     {
247         return _flags & maintProcSupplied;
248     }
249 
250     /**
251      * @brief If the serial number is contained in this structure.
252      *
253      * @return bool
254      */
hasSN() const255     bool hasSN() const
256     {
257         return _flags & snSupplied;
258     }
259 
260     /**
261      * @brief Sets the 8 character null terminated part
262      *        number field to the string passed in.
263      *
264      * @param[in] partNumber - The part number string.
265      */
266     void setPartNumber(const std::string& partNumber);
267 
268     /**
269      * @brief Sets the 4 character CCIN field.
270      *
271      * @param[in] ccin - The CCIN string
272      */
273     void setCCIN(const std::string& ccin);
274 
275     /**
276      * @brief Sets the 12 character serial number field.
277      *
278      * @param[in] serialNumber - The serial number string
279      */
280     void setSerialNumber(const std::string& serialNumber);
281 
282     /**
283      * @brief Sets the 8 character null terminated procedure
284      *        field.  This is in the same field as the part
285      *        number since they are mutually exclusive.
286      *
287      * @param procedure - The procedure name.
288      * @param[in] type - If the procedure is the raw name or
289      *                   the registry name.
290      */
291     void setMaintenanceProcedure(const std::string& procedure,
292                                  CalloutValueType type);
293 
294     /**
295      * @brief Sets the 8 character null terminated symbolic FRU
296      *        field.  This is in the same field as the part
297      *        number since they are mutually exclusive.
298      *
299      * @param[in] symbolicFRU - The symbolic FRU name.
300      * @param[in] type - If the FRU is the raw name or
301      *                   the registry name.
302      */
303     void setSymbolicFRU(const std::string& symbolicFRU, CalloutValueType type);
304 
305     /**
306      * @brief The callout substructure type field. Will be "ID".
307      */
308     uint16_t _type;
309 
310     /**
311      * @brief The size of this callout structure.
312      *
313      * Always a multiple of 4.
314      */
315     uint8_t _size;
316 
317     /**
318      * @brief The flags byte of this substructure.
319      *
320      * See the FailingComponentType and Flags enums
321      */
322     uint8_t _flags;
323 
324     /**
325      * @brief The part number OR maintenance procedure ID,
326      *        depending on what the flags field specifies.
327      *
328      * A NULL terminated ASCII string.
329      */
330     std::array<char, 8> _pnOrProcedureID;
331 
332     /**
333      * @brief The CCIN VPD keyword
334      *
335      * Four ASCII characters, not NULL terminated.
336      */
337     std::array<char, 4> _ccin;
338 
339     /**
340      * @brief The serial number
341      *
342      * Twelve ASCII characters, not NULL terminated.
343      */
344     std::array<char, 12> _sn;
345 };
346 
347 } // namespace src
348 } // namespace pels
349 } // namespace openpower
350