blob: 92f6a91ce9c734d244dae8313a777c5180849e5a [file] [log] [blame]
SunnySrivastava19841356d7e2020-04-24 04:29:35 -05001#include "config.h"
2
SunnySrivastava1984bca5aaa2020-04-21 05:31:04 -05003#include "reader_impl.hpp"
4
Sunny Srivastava6c71c9d2021-04-15 04:43:54 -05005#include "ibm_vpd_utils.hpp"
SunnySrivastava1984bca5aaa2020-04-21 05:31:04 -05006
7#include <com/ibm/VPD/error.hpp>
SunnySrivastava1984bca5aaa2020-04-21 05:31:04 -05008#include <phosphor-logging/elog-errors.hpp>
9#include <xyz/openbmc_project/Common/error.hpp>
10
Patrick Williamsc78d8872023-05-10 07:50:56 -050011#include <algorithm>
12#include <map>
13#include <vector>
14
SunnySrivastava198497f8df02020-05-30 12:05:53 -050015#ifdef ManagerTest
16#include "reader_test.hpp"
17#endif
18
SunnySrivastava1984bca5aaa2020-04-21 05:31:04 -050019namespace openpower
20{
21namespace vpd
22{
23namespace manager
24{
25namespace reader
26{
27
28using namespace phosphor::logging;
29using namespace openpower::vpd::inventory;
30using namespace openpower::vpd::constants;
SunnySrivastava198497f8df02020-05-30 12:05:53 -050031using namespace openpower::vpd::utils::interface;
SunnySrivastava1984bca5aaa2020-04-21 05:31:04 -050032
33using InvalidArgument =
34 sdbusplus::xyz::openbmc_project::Common::Error::InvalidArgument;
35using Argument = xyz::openbmc_project::Common::InvalidArgument;
36using LocationNotFound = sdbusplus::com::ibm::VPD::Error::LocationNotFound;
37
SunnySrivastava1984fb5815a2020-04-24 08:03:52 -050038bool ReaderImpl::isValidLocationCode(const LocationCode& locationCode) const
SunnySrivastava1984bca5aaa2020-04-21 05:31:04 -050039{
40 if ((locationCode.length() < UNEXP_LOCATION_CODE_MIN_LENGTH) ||
SunnySrivastava1984fb5815a2020-04-24 08:03:52 -050041 (locationCode[0] != 'U') ||
SunnySrivastava1984bca5aaa2020-04-21 05:31:04 -050042 ((locationCode.find("fcs", 1, 3) == std::string::npos) &&
43 (locationCode.find("mts", 1, 3) == std::string::npos)))
44 {
SunnySrivastava19841356d7e2020-04-24 04:29:35 -050045 return false;
46 }
47
48 return true;
49}
50
SunnySrivastava1984fb5815a2020-04-24 08:03:52 -050051LocationCode ReaderImpl::getExpandedLocationCode(
52 const LocationCode& locationCode, const NodeNumber& nodeNumber,
SunnySrivastava19841356d7e2020-04-24 04:29:35 -050053 const LocationCodeMap& frusLocationCode) const
54{
SunnySrivastava198497f8df02020-05-30 12:05:53 -050055 // unused at this moment. Hence to avoid warnings
56 (void)nodeNumber;
SunnySrivastava19841356d7e2020-04-24 04:29:35 -050057 if (!isValidLocationCode(locationCode))
58 {
SunnySrivastava1984bca5aaa2020-04-21 05:31:04 -050059 // argument is not valid
60 elog<InvalidArgument>(Argument::ARGUMENT_NAME("LOCATIONCODE"),
61 Argument::ARGUMENT_VALUE(locationCode.c_str()));
62 }
SunnySrivastava1984bca5aaa2020-04-21 05:31:04 -050063 auto iterator = frusLocationCode.find(locationCode);
64 if (iterator == frusLocationCode.end())
65 {
66 // TODO: Implementation of error logic till then throwing invalid
67 // argument
68 // the location code was not found in the system
69 // elog<LocationNotFound>();
70 elog<InvalidArgument>(Argument::ARGUMENT_NAME("LOCATIONCODE"),
71 Argument::ARGUMENT_VALUE(locationCode.c_str()));
72 }
73
SunnySrivastava198497f8df02020-05-30 12:05:53 -050074 std::string expandedLocationCode{};
75#ifndef ManagerTest
76 utility utilObj;
77#endif
78 expandedLocationCode = utilObj.readBusProperty(
Alpana Kumari414d5ae2021-03-04 21:06:35 +000079 iterator->second, IBM_LOCATION_CODE_INF, "LocationCode");
SunnySrivastava1984bca5aaa2020-04-21 05:31:04 -050080 return expandedLocationCode;
81}
82
SunnySrivastava19841356d7e2020-04-24 04:29:35 -050083ListOfPaths
SunnySrivastava1984fb5815a2020-04-24 08:03:52 -050084 ReaderImpl::getFrusAtLocation(const LocationCode& locationCode,
85 const NodeNumber& nodeNumber,
SunnySrivastava19841356d7e2020-04-24 04:29:35 -050086 const LocationCodeMap& frusLocationCode) const
87{
SunnySrivastava198497f8df02020-05-30 12:05:53 -050088 // unused at this moment, to avoid compilation warning
89 (void)nodeNumber;
90
SunnySrivastava1984fb5815a2020-04-24 08:03:52 -050091 // TODO:Implementation related to node number
SunnySrivastava19841356d7e2020-04-24 04:29:35 -050092 if (!isValidLocationCode(locationCode))
93 {
94 // argument is not valid
95 elog<InvalidArgument>(Argument::ARGUMENT_NAME("LOCATIONCODE"),
96 Argument::ARGUMENT_VALUE(locationCode.c_str()));
97 }
98
99 auto range = frusLocationCode.equal_range(locationCode);
100
101 if (range.first == frusLocationCode.end())
102 {
103 // TODO: Implementation of error logic till then throwing invalid
104 // argument
105 // the location code was not found in the system
106 // elog<LocationNotFound>();
107 elog<InvalidArgument>(Argument::ARGUMENT_NAME("LOCATIONCODE"),
108 Argument::ARGUMENT_VALUE(locationCode.c_str()));
109 }
110
111 ListOfPaths inventoryPaths;
112
113 for_each(range.first, range.second,
114 [&inventoryPaths](
115 const inventory::LocationCodeMap::value_type& mappedItem) {
Patrick Williamsc78d8872023-05-10 07:50:56 -0500116 inventoryPaths.push_back(INVENTORY_PATH + mappedItem.second);
117 });
SunnySrivastava19841356d7e2020-04-24 04:29:35 -0500118 return inventoryPaths;
119}
120
SunnySrivastava1984fb5815a2020-04-24 08:03:52 -0500121std::tuple<LocationCode, NodeNumber>
122 ReaderImpl::getCollapsedLocationCode(const LocationCode& locationCode) const
123{
124 // Location code should always start with U and fulfil minimum length
125 // criteria.
126 if (locationCode[0] != 'U' ||
127 locationCode.length() < EXP_LOCATIN_CODE_MIN_LENGTH)
128 {
129 elog<InvalidArgument>(Argument::ARGUMENT_NAME("LOCATIONCODE"),
130 Argument::ARGUMENT_VALUE(locationCode.c_str()));
131 }
132
SunnySrivastava198497f8df02020-05-30 12:05:53 -0500133 std::string fc{};
134#ifndef ManagerTest
135 utility utilObj;
136#endif
137
138 fc = utilObj.readBusProperty(SYSTEM_OBJECT, "com.ibm.ipzvpd.VCEN", "FC");
SunnySrivastava1984fb5815a2020-04-24 08:03:52 -0500139
140 // get the first part of expanded location code to check for FC or TM
141 std::string firstKeyword = locationCode.substr(1, 4);
142
143 LocationCode unexpandedLocationCode{};
144 NodeNumber nodeNummber = INVALID_NODE_NUMBER;
145
146 // check if this value matches the value of FC kwd
147 if (fc.substr(0, 4) ==
148 firstKeyword) // implies this is Ufcs format location code
149 {
150 // period(.) should be there in expanded location code to seggregate FC,
151 // Node number and SE values.
152 size_t nodeStartPos = locationCode.find('.');
153 if (nodeStartPos == std::string::npos)
154 {
155 elog<InvalidArgument>(
156 Argument::ARGUMENT_NAME("LOCATIONCODE"),
157 Argument::ARGUMENT_VALUE(locationCode.c_str()));
158 }
159
160 // second period(.) should be there to end the node details in non
161 // system location code
162 size_t nodeEndPos = locationCode.find('.', nodeStartPos + 1);
163 if (nodeEndPos == std::string::npos)
164 {
165 elog<InvalidArgument>(
166 Argument::ARGUMENT_NAME("LOCATIONCODE"),
167 Argument::ARGUMENT_VALUE(locationCode.c_str()));
168 }
169
170 // skip 3 for '.ND'
171 nodeNummber = std::stoi(locationCode.substr(
172 nodeStartPos + 3, (nodeEndPos - nodeStartPos - 3)));
173
174 // confirm if there are other details apart FC, Node number and SE in
175 // location code
176 if (locationCode.length() > EXP_LOCATIN_CODE_MIN_LENGTH)
177 {
178 unexpandedLocationCode =
179 locationCode[0] + (std::string) "fcs" +
180 locationCode.substr(nodeEndPos + 1 + SE_KWD_LENGTH,
181 std::string::npos);
182 }
183 else
184 {
185 unexpandedLocationCode = "Ufcs";
186 }
187 }
188 else
189 {
SunnySrivastava198497f8df02020-05-30 12:05:53 -0500190 std::string tm{};
SunnySrivastava1984fb5815a2020-04-24 08:03:52 -0500191 // read TM kwd value
Patrick Williamsc78d8872023-05-10 07:50:56 -0500192 tm = utilObj.readBusProperty(SYSTEM_OBJECT, "com.ibm.ipzvpd.VSYS",
193 "TM");
SunnySrivastava198497f8df02020-05-30 12:05:53 -0500194 ;
SunnySrivastava1984fb5815a2020-04-24 08:03:52 -0500195
196 // check if the substr matches to TM kwd
197 if (tm.substr(0, 4) ==
198 firstKeyword) // implies this is Umts format of location code
199 {
200 // system location code will not have any other details and node
201 // number
202 unexpandedLocationCode = "Umts";
203 }
204 // it does not belong to either "fcs" or "mts"
205 else
206 {
207 elog<InvalidArgument>(
208 Argument::ARGUMENT_NAME("LOCATIONCODE"),
209 Argument::ARGUMENT_VALUE(locationCode.c_str()));
210 }
211 }
212
213 return std::make_tuple(unexpandedLocationCode, nodeNummber);
214}
215
216ListOfPaths ReaderImpl::getFRUsByExpandedLocationCode(
217 const inventory::LocationCode& locationCode,
218 const inventory::LocationCodeMap& frusLocationCode) const
219{
220 std::tuple<LocationCode, NodeNumber> locationAndNodePair =
221 getCollapsedLocationCode(locationCode);
222
223 return getFrusAtLocation(std::get<0>(locationAndNodePair),
224 std::get<1>(locationAndNodePair),
225 frusLocationCode);
226}
SunnySrivastava1984bca5aaa2020-04-21 05:31:04 -0500227} // namespace reader
228} // namespace manager
229} // namespace vpd
230} // namespace openpower