1 #pragma once
2 
3 #include "stream.hpp"
4 
5 #include <optional>
6 
7 namespace openpower
8 {
9 namespace pels
10 {
11 namespace src
12 {
13 
14 /**
15  * @class FRUIdentity
16  *
17  * This represents the FRU Identity substructure in the
18  * callout subsection of the SRC PEL section.
19  *
20  * It provides information about the FRU being called out,
21  * such as serial number and part number.  A maintenance
22  * procedure name may be used instead of the part number,
23  * and this would be indicated in the flags field.
24  */
25 class FRUIdentity
26 {
27   public:
28     /**
29      * @brief The failing component type
30      *
31      * Upper nibble of the flags byte
32      */
33     enum FailingComponentType
34     {
35         hardwareFRU = 0x10,
36         codeFRU = 0x20,
37         configError = 0x30,
38         maintenanceProc = 0x40,
39         externalFRU = 0x90,
40         externalCodeFRU = 0xA0,
41         toolFRU = 0xB0,
42         symbolicFRU = 0xC0,
43         symbolicFRUTrustedLocCode = 0xE0
44     };
45 
46     /**
47      * @brief The lower nibble of the flags byte
48      */
49     enum Flags
50     {
51         pnSupplied = 0x08,
52         ccinSupplied = 0x04,
53         maintProcSupplied = 0x02,
54         snSupplied = 0x01
55     };
56 
57     FRUIdentity() = delete;
58     ~FRUIdentity() = default;
59     FRUIdentity(const FRUIdentity&) = default;
60     FRUIdentity& operator=(const FRUIdentity&) = default;
61     FRUIdentity(FRUIdentity&&) = default;
62     FRUIdentity& operator=(FRUIdentity&&) = default;
63 
64     /**
65      * @brief Constructor
66      *
67      * Fills in this class's data fields from the stream.
68      *
69      * @param[in] pel - the PEL data stream
70      */
71     explicit FRUIdentity(Stream& pel);
72 
73     /**
74      * @brief Flatten the object into the stream
75      *
76      * @param[in] stream - The stream to write to
77      */
78     void flatten(Stream& pel) const;
79 
80     /**
81      * @brief Returns the size of this structure when flattened into a PEL
82      *
83      * @return size_t - The size of the section
84      */
85     size_t flattenedSize() const
86     {
87         return _size;
88     }
89 
90     /**
91      * @brief The failing component type for this FRU callout.
92      *
93      * @return FailingComponentType
94      */
95     FailingComponentType failingComponentType() const
96     {
97         return static_cast<FailingComponentType>(_flags & 0xF0);
98     }
99 
100     /**
101      * @brief Returns the part number, if supplied
102      *
103      * @return std::optional<std::string>
104      */
105     std::optional<std::string> getPN() const;
106 
107     /**
108      * @brief Returns the maintenance procedure, if supplied
109      *
110      * @return std::optional<std::string>
111      */
112     std::optional<std::string> getMaintProc() const;
113 
114     /**
115      * @brief Returns the CCIN, if supplied
116      *
117      * @return std::optional<std::string>
118      */
119     std::optional<std::string> getCCIN() const;
120 
121     /**
122      * @brief Returns the serial number, if supplied
123      *
124      * @return std::optional<std::string>
125      */
126     std::optional<std::string> getSN() const;
127 
128     /**
129      * @brief The type identifier value of this structure.
130      */
131     static const uint16_t substructureType = 0x4944; // "ID"
132 
133   private:
134     /**
135      * @brief If the part number is contained in this structure.
136      *
137      * It takes the place of the maintenance procedure ID.
138      *
139      * @return bool
140      */
141     bool hasPN() const
142     {
143         return _flags & pnSupplied;
144     }
145 
146     /**
147      * @brief If the CCIN is contained in this structure.
148      *
149      * @return bool
150      */
151     bool hasCCIN() const
152     {
153         return _flags & ccinSupplied;
154     }
155 
156     /**
157      * @brief If a maintenance procedure is contained in this structure.
158      *
159      * It takes the place of the part number.
160      *
161      * @return bool
162      */
163     bool hasMP() const
164     {
165         return _flags & maintProcSupplied;
166     }
167 
168     /**
169      * @brief If the serial number is contained in this structure.
170      *
171      * @return bool
172      */
173     bool hasSN() const
174     {
175         return _flags & snSupplied;
176     }
177 
178     /**
179      * @brief The callout substructure type field. Will be "ID".
180      */
181     uint16_t _type;
182 
183     /**
184      * @brief The size of this callout structure.
185      *
186      * Always a multiple of 4.
187      */
188     uint8_t _size;
189 
190     /**
191      * @brief The flags byte of this substructure.
192      *
193      * See the FailingComponentType and Flags enums
194      */
195     uint8_t _flags;
196 
197     /**
198      * @brief The part number OR maintenance procedure ID,
199      *        depending on what the flags field specifies.
200      *
201      * A NULL terminated ASCII string.
202      */
203     std::array<char, 8> _pnOrProcedureID;
204 
205     /**
206      * @brief The CCIN VPD keyword
207      *
208      * Four ASCII characters, not NULL terminated.
209      */
210     std::array<char, 4> _ccin;
211 
212     /**
213      * @brief The serial number
214      *
215      * Twelve ASCII characters, not NULL terminated.
216      */
217     std::array<char, 12> _sn;
218 };
219 
220 } // namespace src
221 } // namespace pels
222 } // namespace openpower
223