blob: f1b5c6b78399f65da844802706d94e767ba9d8ba [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
5#include "utils.hpp"
6
SunnySrivastava19841356d7e2020-04-24 04:29:35 -05007#include <algorithm>
SunnySrivastava1984bca5aaa2020-04-21 05:31:04 -05008#include <com/ibm/VPD/error.hpp>
9#include <map>
10#include <phosphor-logging/elog-errors.hpp>
SunnySrivastava19841356d7e2020-04-24 04:29:35 -050011#include <vector>
SunnySrivastava1984bca5aaa2020-04-21 05:31:04 -050012#include <xyz/openbmc_project/Common/error.hpp>
13
14namespace openpower
15{
16namespace vpd
17{
18namespace manager
19{
20namespace reader
21{
22
23using namespace phosphor::logging;
24using namespace openpower::vpd::inventory;
25using namespace openpower::vpd::constants;
26
27using InvalidArgument =
28 sdbusplus::xyz::openbmc_project::Common::Error::InvalidArgument;
29using Argument = xyz::openbmc_project::Common::InvalidArgument;
30using LocationNotFound = sdbusplus::com::ibm::VPD::Error::LocationNotFound;
31
SunnySrivastava1984fb5815a2020-04-24 08:03:52 -050032bool ReaderImpl::isValidLocationCode(const LocationCode& locationCode) const
SunnySrivastava1984bca5aaa2020-04-21 05:31:04 -050033{
34 if ((locationCode.length() < UNEXP_LOCATION_CODE_MIN_LENGTH) ||
SunnySrivastava1984fb5815a2020-04-24 08:03:52 -050035 (locationCode[0] != 'U') ||
SunnySrivastava1984bca5aaa2020-04-21 05:31:04 -050036 ((locationCode.find("fcs", 1, 3) == std::string::npos) &&
37 (locationCode.find("mts", 1, 3) == std::string::npos)))
38 {
SunnySrivastava19841356d7e2020-04-24 04:29:35 -050039 return false;
40 }
41
42 return true;
43}
44
SunnySrivastava1984fb5815a2020-04-24 08:03:52 -050045LocationCode ReaderImpl::getExpandedLocationCode(
46 const LocationCode& locationCode, const NodeNumber& nodeNumber,
SunnySrivastava19841356d7e2020-04-24 04:29:35 -050047 const LocationCodeMap& frusLocationCode) const
48{
49 if (!isValidLocationCode(locationCode))
50 {
SunnySrivastava1984bca5aaa2020-04-21 05:31:04 -050051 // argument is not valid
52 elog<InvalidArgument>(Argument::ARGUMENT_NAME("LOCATIONCODE"),
53 Argument::ARGUMENT_VALUE(locationCode.c_str()));
54 }
55
56 auto iterator = frusLocationCode.find(locationCode);
57 if (iterator == frusLocationCode.end())
58 {
59 // TODO: Implementation of error logic till then throwing invalid
60 // argument
61 // the location code was not found in the system
62 // elog<LocationNotFound>();
63 elog<InvalidArgument>(Argument::ARGUMENT_NAME("LOCATIONCODE"),
64 Argument::ARGUMENT_VALUE(locationCode.c_str()));
65 }
66
67 std::string expandedLocationCode =
68 readBusProperty(iterator->second, LOCATION_CODE_INF, "LocationCode");
69 return expandedLocationCode;
70}
71
SunnySrivastava19841356d7e2020-04-24 04:29:35 -050072ListOfPaths
SunnySrivastava1984fb5815a2020-04-24 08:03:52 -050073 ReaderImpl::getFrusAtLocation(const LocationCode& locationCode,
74 const NodeNumber& nodeNumber,
SunnySrivastava19841356d7e2020-04-24 04:29:35 -050075 const LocationCodeMap& frusLocationCode) const
76{
SunnySrivastava1984fb5815a2020-04-24 08:03:52 -050077 // TODO:Implementation related to node number
SunnySrivastava19841356d7e2020-04-24 04:29:35 -050078 if (!isValidLocationCode(locationCode))
79 {
80 // argument is not valid
81 elog<InvalidArgument>(Argument::ARGUMENT_NAME("LOCATIONCODE"),
82 Argument::ARGUMENT_VALUE(locationCode.c_str()));
83 }
84
85 auto range = frusLocationCode.equal_range(locationCode);
86
87 if (range.first == frusLocationCode.end())
88 {
89 // TODO: Implementation of error logic till then throwing invalid
90 // argument
91 // the location code was not found in the system
92 // elog<LocationNotFound>();
93 elog<InvalidArgument>(Argument::ARGUMENT_NAME("LOCATIONCODE"),
94 Argument::ARGUMENT_VALUE(locationCode.c_str()));
95 }
96
97 ListOfPaths inventoryPaths;
98
99 for_each(range.first, range.second,
100 [&inventoryPaths](
101 const inventory::LocationCodeMap::value_type& mappedItem) {
102 inventoryPaths.push_back(INVENTORY_PATH + mappedItem.second);
103 });
104 return inventoryPaths;
105}
106
SunnySrivastava1984fb5815a2020-04-24 08:03:52 -0500107std::tuple<LocationCode, NodeNumber>
108 ReaderImpl::getCollapsedLocationCode(const LocationCode& locationCode) const
109{
110 // Location code should always start with U and fulfil minimum length
111 // criteria.
112 if (locationCode[0] != 'U' ||
113 locationCode.length() < EXP_LOCATIN_CODE_MIN_LENGTH)
114 {
115 elog<InvalidArgument>(Argument::ARGUMENT_NAME("LOCATIONCODE"),
116 Argument::ARGUMENT_VALUE(locationCode.c_str()));
117 }
118
119 std::string fc =
120 readBusProperty(SYSTEM_OBJECT, "com.ibm.ipzvpd.VCEN", "FC");
121
122 // get the first part of expanded location code to check for FC or TM
123 std::string firstKeyword = locationCode.substr(1, 4);
124
125 LocationCode unexpandedLocationCode{};
126 NodeNumber nodeNummber = INVALID_NODE_NUMBER;
127
128 // check if this value matches the value of FC kwd
129 if (fc.substr(0, 4) ==
130 firstKeyword) // implies this is Ufcs format location code
131 {
132 // period(.) should be there in expanded location code to seggregate FC,
133 // Node number and SE values.
134 size_t nodeStartPos = locationCode.find('.');
135 if (nodeStartPos == std::string::npos)
136 {
137 elog<InvalidArgument>(
138 Argument::ARGUMENT_NAME("LOCATIONCODE"),
139 Argument::ARGUMENT_VALUE(locationCode.c_str()));
140 }
141
142 // second period(.) should be there to end the node details in non
143 // system location code
144 size_t nodeEndPos = locationCode.find('.', nodeStartPos + 1);
145 if (nodeEndPos == std::string::npos)
146 {
147 elog<InvalidArgument>(
148 Argument::ARGUMENT_NAME("LOCATIONCODE"),
149 Argument::ARGUMENT_VALUE(locationCode.c_str()));
150 }
151
152 // skip 3 for '.ND'
153 nodeNummber = std::stoi(locationCode.substr(
154 nodeStartPos + 3, (nodeEndPos - nodeStartPos - 3)));
155
156 // confirm if there are other details apart FC, Node number and SE in
157 // location code
158 if (locationCode.length() > EXP_LOCATIN_CODE_MIN_LENGTH)
159 {
160 unexpandedLocationCode =
161 locationCode[0] + (std::string) "fcs" +
162 locationCode.substr(nodeEndPos + 1 + SE_KWD_LENGTH,
163 std::string::npos);
164 }
165 else
166 {
167 unexpandedLocationCode = "Ufcs";
168 }
169 }
170 else
171 {
172 // read TM kwd value
173 std::string tm =
174 readBusProperty(SYSTEM_OBJECT, "com.ibm.ipzvpd.VSYS", "TM");
175
176 // check if the substr matches to TM kwd
177 if (tm.substr(0, 4) ==
178 firstKeyword) // implies this is Umts format of location code
179 {
180 // system location code will not have any other details and node
181 // number
182 unexpandedLocationCode = "Umts";
183 }
184 // it does not belong to either "fcs" or "mts"
185 else
186 {
187 elog<InvalidArgument>(
188 Argument::ARGUMENT_NAME("LOCATIONCODE"),
189 Argument::ARGUMENT_VALUE(locationCode.c_str()));
190 }
191 }
192
193 return std::make_tuple(unexpandedLocationCode, nodeNummber);
194}
195
196ListOfPaths ReaderImpl::getFRUsByExpandedLocationCode(
197 const inventory::LocationCode& locationCode,
198 const inventory::LocationCodeMap& frusLocationCode) const
199{
200 std::tuple<LocationCode, NodeNumber> locationAndNodePair =
201 getCollapsedLocationCode(locationCode);
202
203 return getFrusAtLocation(std::get<0>(locationAndNodePair),
204 std::get<1>(locationAndNodePair),
205 frusLocationCode);
206}
SunnySrivastava1984bca5aaa2020-04-21 05:31:04 -0500207} // namespace reader
208} // namespace manager
209} // namespace vpd
210} // namespace openpower