blob: 7e9bf1b4df1122b687b30f8aeb7817dc70d9f320 [file] [log] [blame]
Matt Spinler711d51d2019-11-06 09:36:51 -06001/**
2 * Copyright © 2019 IBM Corporation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
Matt Spinlera906c942019-10-08 13:42:05 -050016#include "fru_identity.hpp"
17
Matt Spinlerba0ee002020-03-13 11:24:14 -050018#include "pel_values.hpp"
19
Matt Spinlera906c942019-10-08 13:42:05 -050020namespace openpower
21{
22namespace pels
23{
24namespace src
25{
26
27FRUIdentity::FRUIdentity(Stream& pel)
28{
29 pel >> _type >> _size >> _flags;
30
Matt Spinlerba0ee002020-03-13 11:24:14 -050031 if (hasPN() || hasMP())
Matt Spinlera906c942019-10-08 13:42:05 -050032 {
33 pel.read(_pnOrProcedureID.data(), _pnOrProcedureID.size());
34 }
35
Matt Spinlerba0ee002020-03-13 11:24:14 -050036 if (hasCCIN())
Matt Spinlera906c942019-10-08 13:42:05 -050037 {
38 pel.read(_ccin.data(), _ccin.size());
39 }
40
Matt Spinlerba0ee002020-03-13 11:24:14 -050041 if (hasSN())
Matt Spinlera906c942019-10-08 13:42:05 -050042 {
43 pel.read(_sn.data(), _sn.size());
44 }
45}
46
Matt Spinlera09354b2020-03-13 10:24:52 -050047size_t FRUIdentity::flattenedSize() const
48{
49 size_t size = sizeof(_type) + sizeof(_size) + sizeof(_flags);
50
51 if (hasPN() || hasMP())
52 {
53 size += _pnOrProcedureID.size();
54 }
55
56 if (hasCCIN())
57 {
58 size += _ccin.size();
59 }
60
61 if (hasSN())
62 {
63 size += _sn.size();
64 }
65
66 return size;
67}
68
Matt Spinlerba0ee002020-03-13 11:24:14 -050069FRUIdentity::FRUIdentity(const std::string& partNumber, const std::string& ccin,
70 const std::string& serialNumber)
71{
72 _type = substructureType;
73 _flags = hardwareFRU;
74
75 setPartNumber(partNumber);
76 setCCIN(ccin);
77 setSerialNumber(serialNumber);
78
79 _size = flattenedSize();
80}
81
82FRUIdentity::FRUIdentity(MaintProcedure procedure)
83{
84 _type = substructureType;
85 _flags = maintenanceProc;
86
87 setMaintenanceProcedure(procedure);
88
89 _size = flattenedSize();
90}
91
Matt Spinlera906c942019-10-08 13:42:05 -050092std::optional<std::string> FRUIdentity::getPN() const
93{
94 if (hasPN())
95 {
96 // NULL terminated
97 std::string pn{_pnOrProcedureID.data()};
98 return pn;
99 }
100
101 return std::nullopt;
102}
103
104std::optional<std::string> FRUIdentity::getMaintProc() const
105{
106 if (hasMP())
107 {
108 // NULL terminated
109 std::string mp{_pnOrProcedureID.data()};
110 return mp;
111 }
112
113 return std::nullopt;
114}
115
116std::optional<std::string> FRUIdentity::getCCIN() const
117{
118 if (hasCCIN())
119 {
120 std::string ccin{_ccin.begin(), _ccin.begin() + _ccin.size()};
Matt Spinlerba0ee002020-03-13 11:24:14 -0500121
122 // Don't leave any NULLs in the string (not there usually)
123 if (auto pos = ccin.find('\0'); pos != std::string::npos)
124 {
125 ccin.resize(pos);
126 }
Matt Spinlera906c942019-10-08 13:42:05 -0500127 return ccin;
128 }
129
130 return std::nullopt;
131}
132
133std::optional<std::string> FRUIdentity::getSN() const
134{
135 if (hasSN())
136 {
137 std::string sn{_sn.begin(), _sn.begin() + _sn.size()};
Matt Spinlerba0ee002020-03-13 11:24:14 -0500138
139 // Don't leave any NULLs in the string (not there usually)
140 if (auto pos = sn.find('\0'); pos != std::string::npos)
141 {
142 sn.resize(pos);
143 }
Matt Spinlera906c942019-10-08 13:42:05 -0500144 return sn;
145 }
146
147 return std::nullopt;
148}
149
Matt Spinler724d0d82019-11-06 10:05:36 -0600150void FRUIdentity::flatten(Stream& pel) const
Matt Spinlera906c942019-10-08 13:42:05 -0500151{
152 pel << _type << _size << _flags;
153
154 if (hasPN() || hasMP())
155 {
156 pel.write(_pnOrProcedureID.data(), _pnOrProcedureID.size());
157 }
158
159 if (hasCCIN())
160 {
161 pel.write(_ccin.data(), _ccin.size());
162 }
163
164 if (hasSN())
165 {
166 pel.write(_sn.data(), _sn.size());
167 }
168}
169
Matt Spinlerba0ee002020-03-13 11:24:14 -0500170void FRUIdentity::setPartNumber(const std::string& partNumber)
171{
172 _flags |= pnSupplied;
173 _flags &= ~maintProcSupplied;
174
175 auto pn = partNumber;
176
177 // Strip leading whitespace on this one.
178 while (' ' == pn.front())
179 {
180 pn = pn.substr(1);
181 }
182
183 // Note: strncpy only writes NULLs if pn short
184 strncpy(_pnOrProcedureID.data(), pn.c_str(), _pnOrProcedureID.size());
185
186 // ensure null terminated
187 _pnOrProcedureID.back() = 0;
188}
189
190void FRUIdentity::setCCIN(const std::string& ccin)
191{
192 _flags |= ccinSupplied;
193
194 // Note: _ccin not null terminated, though strncpy writes NULLs if short
195 strncpy(_ccin.data(), ccin.c_str(), _ccin.size());
196}
197
198void FRUIdentity::setSerialNumber(const std::string& serialNumber)
199{
200 _flags |= snSupplied;
201
202 // Note: _sn not null terminated, though strncpy writes NULLs if short
203 strncpy(_sn.data(), serialNumber.c_str(), _sn.size());
204}
205
206void FRUIdentity::setMaintenanceProcedure(MaintProcedure procedure)
207{
208 _flags |= maintProcSupplied;
209 _flags &= ~pnSupplied;
210
211 auto proc = pel_values::getMaintProcedure(procedure);
212
213 strncpy(_pnOrProcedureID.data(), std::get<pel_values::mpNamePos>(*proc),
214 _pnOrProcedureID.size());
215
216 // ensure null terminated
217 _pnOrProcedureID.back() = 0;
218}
219
Matt Spinlera906c942019-10-08 13:42:05 -0500220} // namespace src
221} // namespace pels
222} // namespace openpower