blob: e4f2d8bba85033d2b8c1421855be225d81c62156 [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
Patrick Williams08dc31c2024-08-16 15:21:06 -040083ListOfPaths ReaderImpl::getFrusAtLocation(
84 const LocationCode& locationCode, const NodeNumber& nodeNumber,
85 const LocationCodeMap& frusLocationCode) const
SunnySrivastava19841356d7e2020-04-24 04:29:35 -050086{
SunnySrivastava198497f8df02020-05-30 12:05:53 -050087 // unused at this moment, to avoid compilation warning
88 (void)nodeNumber;
89
SunnySrivastava1984fb5815a2020-04-24 08:03:52 -050090 // TODO:Implementation related to node number
SunnySrivastava19841356d7e2020-04-24 04:29:35 -050091 if (!isValidLocationCode(locationCode))
92 {
93 // argument is not valid
94 elog<InvalidArgument>(Argument::ARGUMENT_NAME("LOCATIONCODE"),
95 Argument::ARGUMENT_VALUE(locationCode.c_str()));
96 }
97
98 auto range = frusLocationCode.equal_range(locationCode);
99
100 if (range.first == frusLocationCode.end())
101 {
102 // TODO: Implementation of error logic till then throwing invalid
103 // argument
104 // the location code was not found in the system
105 // elog<LocationNotFound>();
106 elog<InvalidArgument>(Argument::ARGUMENT_NAME("LOCATIONCODE"),
107 Argument::ARGUMENT_VALUE(locationCode.c_str()));
108 }
109
110 ListOfPaths inventoryPaths;
111
112 for_each(range.first, range.second,
113 [&inventoryPaths](
114 const inventory::LocationCodeMap::value_type& mappedItem) {
Patrick Williams08dc31c2024-08-16 15:21:06 -0400115 inventoryPaths.push_back(INVENTORY_PATH + mappedItem.second);
116 });
SunnySrivastava19841356d7e2020-04-24 04:29:35 -0500117 return inventoryPaths;
118}
119
SunnySrivastava1984fb5815a2020-04-24 08:03:52 -0500120std::tuple<LocationCode, NodeNumber>
121 ReaderImpl::getCollapsedLocationCode(const LocationCode& locationCode) const
122{
123 // Location code should always start with U and fulfil minimum length
124 // criteria.
125 if (locationCode[0] != 'U' ||
126 locationCode.length() < EXP_LOCATIN_CODE_MIN_LENGTH)
127 {
128 elog<InvalidArgument>(Argument::ARGUMENT_NAME("LOCATIONCODE"),
129 Argument::ARGUMENT_VALUE(locationCode.c_str()));
130 }
131
SunnySrivastava198497f8df02020-05-30 12:05:53 -0500132 std::string fc{};
133#ifndef ManagerTest
134 utility utilObj;
135#endif
136
137 fc = utilObj.readBusProperty(SYSTEM_OBJECT, "com.ibm.ipzvpd.VCEN", "FC");
SunnySrivastava1984fb5815a2020-04-24 08:03:52 -0500138
139 // get the first part of expanded location code to check for FC or TM
140 std::string firstKeyword = locationCode.substr(1, 4);
141
142 LocationCode unexpandedLocationCode{};
143 NodeNumber nodeNummber = INVALID_NODE_NUMBER;
144
145 // check if this value matches the value of FC kwd
146 if (fc.substr(0, 4) ==
147 firstKeyword) // implies this is Ufcs format location code
148 {
149 // period(.) should be there in expanded location code to seggregate FC,
150 // Node number and SE values.
151 size_t nodeStartPos = locationCode.find('.');
152 if (nodeStartPos == std::string::npos)
153 {
154 elog<InvalidArgument>(
155 Argument::ARGUMENT_NAME("LOCATIONCODE"),
156 Argument::ARGUMENT_VALUE(locationCode.c_str()));
157 }
158
159 // second period(.) should be there to end the node details in non
160 // system location code
161 size_t nodeEndPos = locationCode.find('.', nodeStartPos + 1);
162 if (nodeEndPos == std::string::npos)
163 {
164 elog<InvalidArgument>(
165 Argument::ARGUMENT_NAME("LOCATIONCODE"),
166 Argument::ARGUMENT_VALUE(locationCode.c_str()));
167 }
168
169 // skip 3 for '.ND'
170 nodeNummber = std::stoi(locationCode.substr(
171 nodeStartPos + 3, (nodeEndPos - nodeStartPos - 3)));
172
173 // confirm if there are other details apart FC, Node number and SE in
174 // location code
175 if (locationCode.length() > EXP_LOCATIN_CODE_MIN_LENGTH)
176 {
177 unexpandedLocationCode =
178 locationCode[0] + (std::string) "fcs" +
179 locationCode.substr(nodeEndPos + 1 + SE_KWD_LENGTH,
180 std::string::npos);
181 }
182 else
183 {
184 unexpandedLocationCode = "Ufcs";
185 }
186 }
187 else
188 {
SunnySrivastava198497f8df02020-05-30 12:05:53 -0500189 std::string tm{};
SunnySrivastava1984fb5815a2020-04-24 08:03:52 -0500190 // read TM kwd value
Patrick Williams08dc31c2024-08-16 15:21:06 -0400191 tm =
192 utilObj.readBusProperty(SYSTEM_OBJECT, "com.ibm.ipzvpd.VSYS", "TM");
SunnySrivastava198497f8df02020-05-30 12:05:53 -0500193 ;
SunnySrivastava1984fb5815a2020-04-24 08:03:52 -0500194
195 // check if the substr matches to TM kwd
196 if (tm.substr(0, 4) ==
197 firstKeyword) // implies this is Umts format of location code
198 {
199 // system location code will not have any other details and node
200 // number
201 unexpandedLocationCode = "Umts";
202 }
203 // it does not belong to either "fcs" or "mts"
204 else
205 {
206 elog<InvalidArgument>(
207 Argument::ARGUMENT_NAME("LOCATIONCODE"),
208 Argument::ARGUMENT_VALUE(locationCode.c_str()));
209 }
210 }
211
212 return std::make_tuple(unexpandedLocationCode, nodeNummber);
213}
214
215ListOfPaths ReaderImpl::getFRUsByExpandedLocationCode(
216 const inventory::LocationCode& locationCode,
217 const inventory::LocationCodeMap& frusLocationCode) const
218{
219 std::tuple<LocationCode, NodeNumber> locationAndNodePair =
220 getCollapsedLocationCode(locationCode);
221
222 return getFrusAtLocation(std::get<0>(locationAndNodePair),
223 std::get<1>(locationAndNodePair),
224 frusLocationCode);
225}
SunnySrivastava1984bca5aaa2020-04-21 05:31:04 -0500226} // namespace reader
227} // namespace manager
228} // namespace vpd
229} // namespace openpower