blob: 3924d3997f807154394d7686c8cfaeafcee6d509 [file] [log] [blame]
Deepak Kodihalli76794492017-02-16 23:48:18 -06001#pragma once
2
SunnySrivastava1984f6d541e2020-02-04 12:50:40 -06003#include "const.hpp"
Alpana Kumarif05effd2021-04-07 07:32:53 -05004#include "store.hpp"
Deepak Kodihalli76794492017-02-16 23:48:18 -06005#include "types.hpp"
6
SunnySrivastava1984d076da82020-03-05 05:33:35 -06007#include <iostream>
Alpana Kumari735dee92022-03-25 01:24:40 -05008#include <nlohmann/json.hpp>
Santosh Puranik53b38ed2022-04-10 23:15:22 +05309#include <optional>
SunnySrivastava1984d076da82020-03-05 05:33:35 -060010
11using namespace std;
SunnySrivastava19849094d4f2020-08-05 09:32:29 -050012
Deepak Kodihalli76794492017-02-16 23:48:18 -060013namespace openpower
14{
15namespace vpd
16{
SunnySrivastava1984945a02d2020-05-06 01:55:41 -050017
Santosh Puranik6b2b5372022-06-02 20:49:02 +053018// Map to hold record, kwd pair which can be re-stored at standby.
19// The list of keywords for VSYS record is as per the S0 system. Should
20// be updated for another type of systems
21static const std::unordered_map<std::string, std::vector<std::string>>
22 svpdKwdMap{{"VSYS", {"BR", "TM", "SE", "SU", "RB", "WN", "RG"}},
23 {"VCEN", {"FC", "SE"}},
24 {"LXR0", {"LX"}},
25 {"UTIL", {"D0"}}};
26
Santosh Puranikbd011b22020-01-23 04:05:25 -060027/** @brief Return the hex representation of the incoming byte
28 *
29 * @param [in] c - The input byte
30 * @returns The hex representation of the byte as a character.
31 */
32constexpr auto toHex(size_t c)
33{
34 constexpr auto map = "0123456789abcdef";
35 return map[c];
36}
Deepak Kodihalli76794492017-02-16 23:48:18 -060037
38namespace inventory
39{
PriyangaRamasamyc2fe40f2021-03-02 06:27:33 -060040/** @brief API to obtain a dictionary of path -> services
SunnySrivastava19849094d4f2020-08-05 09:32:29 -050041 * where path is in subtree and services is of the type
42 * returned by the GetObject method.
43 *
44 * @param [in] root - Root path for object subtree
45 * @param [in] depth - Maximum subtree depth required
46 * @param [in] interfaces - Array to interfaces for which
47 * result is required.
48 * @return A dictionary of Path -> services
49 */
50MapperResponse
51 getObjectSubtreeForInterfaces(const std::string& root, const int32_t depth,
52 const std::vector<std::string>& interfaces);
53
Deepak Kodihalli76794492017-02-16 23:48:18 -060054} // namespace inventory
55
SunnySrivastava1984f6d541e2020-02-04 12:50:40 -060056/**@brief This API reads 2 Bytes of data and swap the read data
57 * @param[in] iterator- Pointer pointing to the data to be read
58 * @return returns 2 Byte data read at the given pointer
59 */
60openpower::vpd::constants::LE2ByteData
61 readUInt16LE(Binary::const_iterator iterator);
62
SunnySrivastava1984d076da82020-03-05 05:33:35 -060063/** @brief Encodes a keyword for D-Bus.
64 * @param[in] kw - kwd data in string format
65 * @param[in] encoding - required for kwd data
66 */
67string encodeKeyword(const string& kw, const string& encoding);
SunnySrivastava198443306542020-04-01 02:50:20 -050068
69/** @brief Reads a property from the inventory manager given object path,
70 * intreface and property.
71 * @param[in] obj - object path
72 * @param[in] inf - interface
73 * @param[in] prop - property whose value is fetched
74 * @return [out] - value of the property
75 */
76string readBusProperty(const string& obj, const string& inf,
77 const string& prop);
SunnySrivastava1984a20be8e2020-08-26 02:00:50 -050078
Priyanga Ramasamyf1449cd2022-07-13 04:28:30 -050079/** @brief A templated function to read D-Bus properties.
80 *
81 * @param[in] service - Service path
82 * @param[in] object - object path
83 * @param[in] inf - interface
84 * @param[in] prop - property whose value is fetched
85 * @return The property value of its own type.
86 */
87template <typename T>
88T readDBusProperty(const string& service, const string& object,
89 const string& inf, const string& prop)
90{
91 T retVal{};
92 try
93 {
94 auto bus = sdbusplus::bus::new_default();
95 auto properties =
96 bus.new_method_call(service.c_str(), object.c_str(),
97 "org.freedesktop.DBus.Properties", "Get");
98 properties.append(inf);
99 properties.append(prop);
100 auto result = bus.call(properties);
101 result.read(retVal);
102 }
103 catch (const sdbusplus::exception::SdBusError& e)
104 {
105 std::cerr << e.what();
106 }
107 return retVal;
108}
109
SunnySrivastava1984a20be8e2020-08-26 02:00:50 -0500110/**
111 * @brief API to create PEL entry
Sunny Srivastava0746eee2021-03-22 13:36:54 -0500112 * @param[in] additionalData - Map holding the additional data
113 * @param[in] sev - Severity
114 * @param[in] errIntf - error interface
SunnySrivastava1984a20be8e2020-08-26 02:00:50 -0500115 */
116void createPEL(const std::map<std::string, std::string>& additionalData,
Sunny Srivastava0746eee2021-03-22 13:36:54 -0500117 const constants::PelSeverity& sev, const std::string& errIntf);
SunnySrivastava19849094d4f2020-08-05 09:32:29 -0500118
PriyangaRamasamyc0a534f2020-08-24 21:29:18 +0530119/**
120 * @brief getVpdFilePath
121 * Get vpd file path corresponding to the given object path.
122 * @param[in] - json file path
123 * @param[in] - Object path
124 * @return - Vpd file path
125 */
126inventory::VPDfilepath getVpdFilePath(const string& jsonFile,
127 const std::string& ObjPath);
128
129/**
130 * @brief isPathInJson
131 * API which checks for the presence of the given eeprom path in the given json.
132 * @param[in] - eepromPath
133 * @return - true if the eeprom is present in the json; false otherwise
134 */
135bool isPathInJson(const std::string& eepromPath);
136
137/**
138 * @brief isRecKwInDbusJson
139 * API which checks whether the given keyword under the given record is to be
140 * published on dbus or not. Checks against the keywords present in
141 * dbus_property.json.
142 * @param[in] - record name
143 * @param[in] - keyword name
144 * @return - true if the record-keyword pair is present in dbus_property.json;
145 * false otherwise.
146 */
147bool isRecKwInDbusJson(const std::string& record, const std::string& keyword);
148
Sunny Srivastava6c71c9d2021-04-15 04:43:54 -0500149/**
150 * @brief Check the type of VPD.
151 *
152 * Checks the type of vpd based on the start tag.
153 * @param[in] vector - Vpd data in vector format
154 *
155 * @return enum of type vpdType
156 */
157constants::vpdType vpdTypeCheck(const Binary& vector);
158
SunnySrivastava19849a195542020-09-07 06:04:50 -0500159/*
160 * @brief This method does nothing. Just an empty function to return null
161 * at the end of variadic template args
162 */
163inline string getCommand()
164{
165 return "";
166}
167
168/**
169 * @brief This function to arrange all arguments to make commandy
170 * @param[in] arguments to create the command
171 * @return cmd - command string
172 */
173template <typename T, typename... Types>
174inline string getCommand(T arg1, Types... args)
175{
176 string cmd = " " + arg1 + getCommand(args...);
177
178 return cmd;
179}
180
181/**
182 * @brief This API takes arguments, creates a shell command line and executes
183 * them.
184 * @param[in] arguments for command
185 * @returns output of that command
186 */
187template <typename T, typename... Types>
188inline vector<string> executeCmd(T&& path, Types... args)
189{
190 vector<string> stdOutput;
191 array<char, 128> buffer;
192
193 string cmd = path + getCommand(args...);
194
195 unique_ptr<FILE, decltype(&pclose)> pipe(popen(cmd.c_str(), "r"), pclose);
196 if (!pipe)
197 {
198 throw runtime_error("popen() failed!");
199 }
200 while (fgets(buffer.data(), buffer.size(), pipe.get()) != nullptr)
201 {
202 stdOutput.emplace_back(buffer.data());
203 }
204
205 return stdOutput;
206}
207
Alpana Kumarif05effd2021-04-07 07:32:53 -0500208/** @brief This API checks for IM and HW keywords, and based
209 * on these values decides which system json to be used.
210 * @param[in] vpdMap - parsed vpd
211 * @returns System json path
212 */
213string getSystemsJson(const Parsed& vpdMap);
214
215/** @brief Reads HW Keyword from the vpd
216 * @param[in] vpdMap - parsed vpd
217 * @returns value of HW Keyword
218 */
219const string getHW(const Parsed& vpdMap);
220
221/** @brief Reads IM Keyword from the vpd
222 * @param[in] vpdMap - parsed vpd
223 * @returns value of IM Keyword
224 */
225const string getIM(const Parsed& vpdMap);
226
PriyangaRamasamy647868e2020-09-08 17:03:19 +0530227/** @brief Translate udev event generated path to a generic /sys/bus eeprom path
228 * @param[io] file - path generated from udev event.
229 */
230void udevToGenericPath(string& file);
PriyangaRamasamyc2fe40f2021-03-02 06:27:33 -0600231
232/**
233 * @brief API to generate a vpd name in some pattern.
234 * This vpd-name denotes name of the bad vpd file.
235 * For i2c eeproms - the pattern of the vpd-name will be
236 * i2c-<bus-number>-<eeprom-address>. For spi eeproms - the pattern of the
237 * vpd-name will be spi-<spi-number>.
238 *
239 * @param[in] file - file path of the vpd
240 * @return the vpd-name.
241 */
242string getBadVpdName(const string& file);
243
244/**
245 * @brief API which dumps the broken/bad vpd in a directory
246 * When the vpd is bad, this api places the bad vpd file inside
247 * "/tmp/bad-vpd" in BMC, in order to collect bad VPD data as a part of user
248 * initiated BMC dump.
249 *
250 * @param[in] file - bad vpd file path
251 * @param[in] vpdVector - bad vpd vector
252 */
253void dumpBadVpd(const std::string& file, const Binary& vpdVector);
alpana077ce68722021-07-25 13:23:59 -0500254
255/*
256 * @brief This function fetches the value for given keyword in the given record
257 * from vpd data and returns this value.
258 *
259 * @param[in] vpdMap - vpd to find out the data
260 * @param[in] rec - Record under which desired keyword exists
261 * @param[in] kwd - keyword to read the data from
262 *
263 * @returns keyword value if record/keyword combination found
264 * empty string if record or keyword is not found.
265 */
266const string getKwVal(const Parsed& vpdMap, const string& rec,
267 const string& kwd);
268
Alpana Kumarib17dd3b2020-10-01 00:18:10 -0500269/** @brief This creates a complete command using all it's input parameters,
270 * to bind or unbind the driver.
271 * @param[in] devNameAddr - device address on that bus
272 * @param[in] busType - i2c, spi
273 * @param[in] driverType - type of driver like at24
274 * @param[in] bindOrUnbind - either bind or unbind
275 * @returns Command to bind or unbind the driver.
276 */
277inline string createBindUnbindDriverCmnd(const string& devNameAddr,
278 const string& busType,
279 const string& driverType,
280 const string& bindOrUnbind)
281{
282 return ("echo " + devNameAddr + " > /sys/bus/" + busType + "/drivers/" +
283 driverType + "/" + bindOrUnbind);
284}
285
Priyanga Ramasamy02434932021-10-07 16:26:05 -0500286/**
287 * @brief Get Printable Value
288 *
289 * Checks if the vector value has non printable characters.
290 * Returns hex value if non printable char is found else
291 * returns ascii value.
292 *
293 * @param[in] vector - Reference of the Binary vector
294 * @return printable value - either in hex or in ascii.
295 */
Priyanga Ramasamyc9ecf8e2021-10-08 02:28:52 -0500296string getPrintableValue(const Binary& vec);
297
298/**
299 * @brief Convert byte array to hex string.
300 * @param[in] vec - byte array
301 * @return hexadecimal string of bytes.
302 */
303string byteArrayToHexString(const Binary& vec);
Priyanga Ramasamy02434932021-10-07 16:26:05 -0500304
Priyanga Ramasamyaa8a8932022-01-27 09:12:41 -0600305/**
Santosh Puranik53b38ed2022-04-10 23:15:22 +0530306 * @brief Return presence of the FRU.
307 *
308 * This API returns the presence information of the FRU corresponding to the
309 * given EEPROM. If the JSON contains no information about presence detect, this
310 * will return an empty optional. Else it will get the presence GPIO information
311 * from the JSON and return the appropriate present status.
312 * In case of GPIO find/read errors, it will return false.
313 *
314 * @param[in] json - The VPD JSON
315 * @param[in] file - EEPROM file path
316 * @return Empty optional if there is no presence info. Else returns presence
317 * based on the GPIO read.
318 */
319std::optional<bool> isPresent(const nlohmann::json& json, const string& file);
320
321/**
322 * @brief Performs any pre-action needed to get the FRU setup for
323 * collection.
Alpana Kumari735dee92022-03-25 01:24:40 -0500324 *
325 * @param[in] json - json object
326 * @param[in] file - eeprom file path
327 * @return - success or failure
328 */
329bool executePreAction(const nlohmann::json& json, const string& file);
330
331/**
332 * @brief This API will be called at the end of VPD collection to perform any
333 * post actions.
334 *
335 * @param[in] json - json object
336 * @param[in] file - eeprom file path
337 */
338void executePostFailAction(const nlohmann::json& json, const string& file);
339
340/**
Priyanga Ramasamyaa8a8932022-01-27 09:12:41 -0600341 * @brief Helper function to insert or merge in map.
342 *
343 * This method checks in the given inventory::InterfaceMap if the given
344 * interface key is existing or not. If the interface key already exists, given
345 * property map is inserted into it. If the key does'nt exist then given
346 * interface and property map pair is newly created. If the property present in
347 * propertymap already exist in the InterfaceMap, then the new property value is
348 * ignored.
349 *
350 * @param[in,out] map - map object of type inventory::InterfaceMap only.
351 * @param[in] interface - Interface name.
352 * @param[in] property - new property map that needs to be emplaced.
353 */
354void insertOrMerge(inventory::InterfaceMap& map,
355 const inventory::Interface& interface,
356 inventory::PropertyMap&& property);
357
Santosh Puranikf2d3b532022-04-19 06:44:07 -0500358/**
359 * @brief Utility API to set a D-Bus property
360 *
361 * This calls org.freedesktop.DBus.Properties;Set method with the supplied
362 * arguments
363 *
364 * @tparam T Template type of the D-Bus property
365 * @param service[in] - The D-Bus service name.
366 * @param object[in] - The D-Bus object on which the property is to be set.
367 * @param interface[in] - The D-Bus interface to which the property belongs.
368 * @param propertyName[in] - The name of the property to set.
369 * @param propertyValue[in] - The value of the property.
370 */
371template <typename T>
372void setBusProperty(const std::string& service, const std::string& object,
373 const std::string& interface,
374 const std::string& propertyName,
375 const std::variant<T>& propertyValue)
376{
377 try
378 {
379 auto bus = sdbusplus::bus::new_default();
380 auto method =
381 bus.new_method_call(service.c_str(), object.c_str(),
382 "org.freedesktop.DBus.Properties", "Set");
383 method.append(interface);
384 method.append(propertyName);
385 method.append(propertyValue);
386
387 bus.call(method);
388 }
389 catch (const sdbusplus::exception::SdBusError& e)
390 {
391 std::cerr << e.what() << std::endl;
392 }
393}
394
395/**
396 * @brief Reads BIOS Attribute by name.
397 *
398 * @param attrName[in] - The BIOS attribute name.
399 * @return std::variant<int64_t, std::string> - The BIOS attribute value.
400 */
401std::variant<int64_t, std::string>
402 readBIOSAttribute(const std::string& attrName);
Priyanga Ramasamy335873f2022-05-18 01:31:54 -0500403
404/**
405 * @brief Returns the power state for chassis0
406 * @return The chassis power state.
407 */
408std::string getPowerState();
Santosh Puranik6b2b5372022-06-02 20:49:02 +0530409
410/**
411 * @brief Reads VPD from the supplied EEPROM
412 *
413 * This function reads the given VPD EEPROM file and returns its contents as a
414 * byte array. It handles any offsets into the file that need to be taken care
415 * of by looking up the VPD JSON for a possible offset key.
416 *
417 * @param js[in] - The VPD JSON Object
418 * @param file[in] - The path to the EEPROM to read
419 * @return A byte array containing the raw VPD.
420 */
421Binary getVpdDataInVector(const nlohmann::json& js, const std::string& file);
Patrick Venturec83c4dc2018-11-01 16:29:18 -0700422} // namespace vpd
Santosh Puranikf2d3b532022-04-19 06:44:07 -0500423} // namespace openpower