blob: 08eb32b8551858a1ef689e1bc947fdf6bb0c35ee [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
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
SunnySrivastava198497f8df02020-05-30 12:05:53 -050014#ifdef ManagerTest
15#include "reader_test.hpp"
16#endif
17
SunnySrivastava1984bca5aaa2020-04-21 05:31:04 -050018namespace openpower
19{
20namespace vpd
21{
22namespace manager
23{
24namespace reader
25{
26
27using namespace phosphor::logging;
28using namespace openpower::vpd::inventory;
29using namespace openpower::vpd::constants;
SunnySrivastava198497f8df02020-05-30 12:05:53 -050030using namespace openpower::vpd::utils::interface;
SunnySrivastava1984bca5aaa2020-04-21 05:31:04 -050031
32using InvalidArgument =
33 sdbusplus::xyz::openbmc_project::Common::Error::InvalidArgument;
34using Argument = xyz::openbmc_project::Common::InvalidArgument;
35using LocationNotFound = sdbusplus::com::ibm::VPD::Error::LocationNotFound;
36
SunnySrivastava1984fb5815a2020-04-24 08:03:52 -050037bool ReaderImpl::isValidLocationCode(const LocationCode& locationCode) const
SunnySrivastava1984bca5aaa2020-04-21 05:31:04 -050038{
39 if ((locationCode.length() < UNEXP_LOCATION_CODE_MIN_LENGTH) ||
SunnySrivastava1984fb5815a2020-04-24 08:03:52 -050040 (locationCode[0] != 'U') ||
SunnySrivastava1984bca5aaa2020-04-21 05:31:04 -050041 ((locationCode.find("fcs", 1, 3) == std::string::npos) &&
42 (locationCode.find("mts", 1, 3) == std::string::npos)))
43 {
SunnySrivastava19841356d7e2020-04-24 04:29:35 -050044 return false;
45 }
46
47 return true;
48}
49
SunnySrivastava1984fb5815a2020-04-24 08:03:52 -050050LocationCode ReaderImpl::getExpandedLocationCode(
51 const LocationCode& locationCode, const NodeNumber& nodeNumber,
SunnySrivastava19841356d7e2020-04-24 04:29:35 -050052 const LocationCodeMap& frusLocationCode) const
53{
SunnySrivastava198497f8df02020-05-30 12:05:53 -050054 // unused at this moment. Hence to avoid warnings
55 (void)nodeNumber;
SunnySrivastava19841356d7e2020-04-24 04:29:35 -050056 if (!isValidLocationCode(locationCode))
57 {
SunnySrivastava1984bca5aaa2020-04-21 05:31:04 -050058 // argument is not valid
59 elog<InvalidArgument>(Argument::ARGUMENT_NAME("LOCATIONCODE"),
60 Argument::ARGUMENT_VALUE(locationCode.c_str()));
61 }
SunnySrivastava1984bca5aaa2020-04-21 05:31:04 -050062 auto iterator = frusLocationCode.find(locationCode);
63 if (iterator == frusLocationCode.end())
64 {
65 // TODO: Implementation of error logic till then throwing invalid
66 // argument
67 // the location code was not found in the system
68 // elog<LocationNotFound>();
69 elog<InvalidArgument>(Argument::ARGUMENT_NAME("LOCATIONCODE"),
70 Argument::ARGUMENT_VALUE(locationCode.c_str()));
71 }
72
SunnySrivastava198497f8df02020-05-30 12:05:53 -050073 std::string expandedLocationCode{};
74#ifndef ManagerTest
75 utility utilObj;
76#endif
77 expandedLocationCode = utilObj.readBusProperty(
78 iterator->second, LOCATION_CODE_INF, "LocationCode");
SunnySrivastava1984bca5aaa2020-04-21 05:31:04 -050079 return expandedLocationCode;
80}
81
SunnySrivastava19841356d7e2020-04-24 04:29:35 -050082ListOfPaths
SunnySrivastava1984fb5815a2020-04-24 08:03:52 -050083 ReaderImpl::getFrusAtLocation(const LocationCode& locationCode,
84 const NodeNumber& nodeNumber,
SunnySrivastava19841356d7e2020-04-24 04:29:35 -050085 const LocationCodeMap& frusLocationCode) const
86{
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) {
115 inventoryPaths.push_back(INVENTORY_PATH + mappedItem.second);
116 });
117 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
SunnySrivastava198497f8df02020-05-30 12:05:53 -0500191 tm =
192 utilObj.readBusProperty(SYSTEM_OBJECT, "com.ibm.ipzvpd.VSYS", "TM");
193 ;
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