blob: 2b75c7d17d694b487cf7885fbdee481b31fed896 [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
Deepak Kodihalli76794492017-02-16 23:48:18 -060011namespace openpower
12{
13namespace vpd
14{
SunnySrivastava1984945a02d2020-05-06 01:55:41 -050015
Santosh Puranik6b2b5372022-06-02 20:49:02 +053016// Map to hold record, kwd pair which can be re-stored at standby.
17// The list of keywords for VSYS record is as per the S0 system. Should
18// be updated for another type of systems
19static const std::unordered_map<std::string, std::vector<std::string>>
Priyanga Ramasamyafb71f72022-10-21 02:17:19 -050020 svpdKwdMap{{"VSYS", {"BR", "TM", "SE", "SU", "RB", "WN", "RG", "FV"}},
Santosh Puranik6b2b5372022-06-02 20:49:02 +053021 {"VCEN", {"FC", "SE"}},
22 {"LXR0", {"LX"}},
23 {"UTIL", {"D0"}}};
24
Santosh Puranikbd011b22020-01-23 04:05:25 -060025/** @brief Return the hex representation of the incoming byte
26 *
27 * @param [in] c - The input byte
28 * @returns The hex representation of the byte as a character.
29 */
30constexpr auto toHex(size_t c)
31{
32 constexpr auto map = "0123456789abcdef";
33 return map[c];
34}
Deepak Kodihalli76794492017-02-16 23:48:18 -060035
36namespace inventory
37{
PriyangaRamasamyc2fe40f2021-03-02 06:27:33 -060038/** @brief API to obtain a dictionary of path -> services
SunnySrivastava19849094d4f2020-08-05 09:32:29 -050039 * where path is in subtree and services is of the type
40 * returned by the GetObject method.
41 *
42 * @param [in] root - Root path for object subtree
43 * @param [in] depth - Maximum subtree depth required
44 * @param [in] interfaces - Array to interfaces for which
45 * result is required.
46 * @return A dictionary of Path -> services
47 */
48MapperResponse
49 getObjectSubtreeForInterfaces(const std::string& root, const int32_t depth,
50 const std::vector<std::string>& interfaces);
51
Deepak Kodihalli76794492017-02-16 23:48:18 -060052} // namespace inventory
53
SunnySrivastava1984f6d541e2020-02-04 12:50:40 -060054/**@brief This API reads 2 Bytes of data and swap the read data
55 * @param[in] iterator- Pointer pointing to the data to be read
56 * @return returns 2 Byte data read at the given pointer
57 */
58openpower::vpd::constants::LE2ByteData
59 readUInt16LE(Binary::const_iterator iterator);
60
SunnySrivastava1984d076da82020-03-05 05:33:35 -060061/** @brief Encodes a keyword for D-Bus.
62 * @param[in] kw - kwd data in string format
63 * @param[in] encoding - required for kwd data
64 */
Priyanga Ramasamye0084322022-09-27 06:28:33 -050065std::string encodeKeyword(const std::string& kw, const std::string& encoding);
SunnySrivastava198443306542020-04-01 02:50:20 -050066
67/** @brief Reads a property from the inventory manager given object path,
68 * intreface and property.
69 * @param[in] obj - object path
70 * @param[in] inf - interface
71 * @param[in] prop - property whose value is fetched
72 * @return [out] - value of the property
73 */
Priyanga Ramasamye0084322022-09-27 06:28:33 -050074std::string readBusProperty(const std::string& obj, const std::string& inf,
75 const std::string& prop);
SunnySrivastava1984a20be8e2020-08-26 02:00:50 -050076
Priyanga Ramasamyf1449cd2022-07-13 04:28:30 -050077/** @brief A templated function to read D-Bus properties.
78 *
79 * @param[in] service - Service path
80 * @param[in] object - object path
81 * @param[in] inf - interface
82 * @param[in] prop - property whose value is fetched
83 * @return The property value of its own type.
84 */
85template <typename T>
Priyanga Ramasamye0084322022-09-27 06:28:33 -050086T readDBusProperty(const std::string& service, const std::string& object,
87 const std::string& inf, const std::string& prop)
Priyanga Ramasamyf1449cd2022-07-13 04:28:30 -050088{
89 T retVal{};
90 try
91 {
92 auto bus = sdbusplus::bus::new_default();
93 auto properties =
94 bus.new_method_call(service.c_str(), object.c_str(),
95 "org.freedesktop.DBus.Properties", "Get");
96 properties.append(inf);
97 properties.append(prop);
98 auto result = bus.call(properties);
99 result.read(retVal);
100 }
101 catch (const sdbusplus::exception::SdBusError& e)
102 {
103 std::cerr << e.what();
104 }
105 return retVal;
106}
107
Priyanga Ramasamy43ffcf72022-06-08 14:10:11 -0500108/** @brief A templated method to get all D-Bus properties
109 *
110 * @param[in] service - Service path
111 * @param[in] object - Object path
112 * @param[in] inf - Interface
113 *
114 * @return All properties under the given interface.
115 */
116template <typename T>
117T getAllDBusProperty(const std::string& service, const std::string& object,
118 const std::string& inf)
119{
120 T retVal{};
121 try
122 {
123 auto bus = sdbusplus::bus::new_default();
124 auto allProperties =
125 bus.new_method_call(service.c_str(), object.c_str(),
126 "org.freedesktop.DBus.Properties", "GetAll");
127 allProperties.append(inf);
128
129 auto result = bus.call(allProperties);
130 result.read(retVal);
131 }
132 catch (const sdbusplus::exception::SdBusError& e)
133 {
134 std::cerr << e.what();
135 }
136 return retVal;
137}
138
SunnySrivastava1984a20be8e2020-08-26 02:00:50 -0500139/**
140 * @brief API to create PEL entry
Sunny Srivastavaa2ddc962022-06-29 08:53:16 -0500141 * The api makes synchronous call to phosphor-logging create api.
Sunny Srivastava0746eee2021-03-22 13:36:54 -0500142 * @param[in] additionalData - Map holding the additional data
143 * @param[in] sev - Severity
144 * @param[in] errIntf - error interface
SunnySrivastava1984a20be8e2020-08-26 02:00:50 -0500145 */
Sunny Srivastavaa2ddc962022-06-29 08:53:16 -0500146void createSyncPEL(const std::map<std::string, std::string>& additionalData,
147 const constants::PelSeverity& sev,
148 const std::string& errIntf);
149
150/**
151 * @brief Api to create PEL.
152 * A wrapper api through which sync/async call to phosphor-logging create api
153 * can be made as and when required.
154 * sdBus as nullptr will result in sync call else async call will be made with
155 * just "DESCRIPTION" key/value pair in additional data.
156 * To make asyn call with more fields in additional data call
157 * "sd_bus_call_method_async" in place.
158 *
159 * @param[in] additionalData - Map of additional data.
160 * @param[in] sev - severity of the PEL.
161 * @param[in] errIntf - Error interface to be used in PEL.
162 * @param[in] sdBus - Pointer to Sd-Bus
163 */
SunnySrivastava1984a20be8e2020-08-26 02:00:50 -0500164void createPEL(const std::map<std::string, std::string>& additionalData,
Sunny Srivastavaa2ddc962022-06-29 08:53:16 -0500165 const constants::PelSeverity& sev, const std::string& errIntf,
166 sd_bus* sdBus);
SunnySrivastava19849094d4f2020-08-05 09:32:29 -0500167
PriyangaRamasamyc0a534f2020-08-24 21:29:18 +0530168/**
169 * @brief getVpdFilePath
170 * Get vpd file path corresponding to the given object path.
171 * @param[in] - json file path
172 * @param[in] - Object path
173 * @return - Vpd file path
174 */
Priyanga Ramasamye0084322022-09-27 06:28:33 -0500175inventory::VPDfilepath getVpdFilePath(const std::string& jsonFile,
PriyangaRamasamyc0a534f2020-08-24 21:29:18 +0530176 const std::string& ObjPath);
177
178/**
179 * @brief isPathInJson
180 * API which checks for the presence of the given eeprom path in the given json.
181 * @param[in] - eepromPath
182 * @return - true if the eeprom is present in the json; false otherwise
183 */
184bool isPathInJson(const std::string& eepromPath);
185
186/**
187 * @brief isRecKwInDbusJson
188 * API which checks whether the given keyword under the given record is to be
189 * published on dbus or not. Checks against the keywords present in
190 * dbus_property.json.
191 * @param[in] - record name
192 * @param[in] - keyword name
193 * @return - true if the record-keyword pair is present in dbus_property.json;
194 * false otherwise.
195 */
196bool isRecKwInDbusJson(const std::string& record, const std::string& keyword);
197
Sunny Srivastava6c71c9d2021-04-15 04:43:54 -0500198/**
199 * @brief Check the type of VPD.
200 *
201 * Checks the type of vpd based on the start tag.
202 * @param[in] vector - Vpd data in vector format
203 *
204 * @return enum of type vpdType
205 */
206constants::vpdType vpdTypeCheck(const Binary& vector);
207
SunnySrivastava19849a195542020-09-07 06:04:50 -0500208/*
209 * @brief This method does nothing. Just an empty function to return null
210 * at the end of variadic template args
211 */
Priyanga Ramasamye0084322022-09-27 06:28:33 -0500212inline std::string getCommand()
SunnySrivastava19849a195542020-09-07 06:04:50 -0500213{
214 return "";
215}
216
217/**
218 * @brief This function to arrange all arguments to make commandy
219 * @param[in] arguments to create the command
220 * @return cmd - command string
221 */
222template <typename T, typename... Types>
Priyanga Ramasamye0084322022-09-27 06:28:33 -0500223inline std::string getCommand(T arg1, Types... args)
SunnySrivastava19849a195542020-09-07 06:04:50 -0500224{
Priyanga Ramasamye0084322022-09-27 06:28:33 -0500225 std::string cmd = " " + arg1 + getCommand(args...);
SunnySrivastava19849a195542020-09-07 06:04:50 -0500226
227 return cmd;
228}
229
230/**
231 * @brief This API takes arguments, creates a shell command line and executes
232 * them.
233 * @param[in] arguments for command
234 * @returns output of that command
235 */
236template <typename T, typename... Types>
Priyanga Ramasamye0084322022-09-27 06:28:33 -0500237inline std::vector<std::string> executeCmd(T&& path, Types... args)
SunnySrivastava19849a195542020-09-07 06:04:50 -0500238{
Priyanga Ramasamye0084322022-09-27 06:28:33 -0500239 std::vector<std::string> stdOutput;
240 std::array<char, 128> buffer;
SunnySrivastava19849a195542020-09-07 06:04:50 -0500241
Priyanga Ramasamye0084322022-09-27 06:28:33 -0500242 std::string cmd = path + getCommand(args...);
SunnySrivastava19849a195542020-09-07 06:04:50 -0500243
Priyanga Ramasamye0084322022-09-27 06:28:33 -0500244 std::unique_ptr<FILE, decltype(&pclose)> pipe(popen(cmd.c_str(), "r"),
245 pclose);
SunnySrivastava19849a195542020-09-07 06:04:50 -0500246 if (!pipe)
247 {
Priyanga Ramasamye0084322022-09-27 06:28:33 -0500248 throw std::runtime_error("popen() failed!");
SunnySrivastava19849a195542020-09-07 06:04:50 -0500249 }
250 while (fgets(buffer.data(), buffer.size(), pipe.get()) != nullptr)
251 {
252 stdOutput.emplace_back(buffer.data());
253 }
254
255 return stdOutput;
256}
257
Alpana Kumarif05effd2021-04-07 07:32:53 -0500258/** @brief This API checks for IM and HW keywords, and based
259 * on these values decides which system json to be used.
260 * @param[in] vpdMap - parsed vpd
261 * @returns System json path
262 */
Priyanga Ramasamye0084322022-09-27 06:28:33 -0500263std::string getSystemsJson(const Parsed& vpdMap);
Alpana Kumarif05effd2021-04-07 07:32:53 -0500264
265/** @brief Reads HW Keyword from the vpd
266 * @param[in] vpdMap - parsed vpd
267 * @returns value of HW Keyword
268 */
Priyanga Ramasamye0084322022-09-27 06:28:33 -0500269const std::string getHW(const Parsed& vpdMap);
Alpana Kumarif05effd2021-04-07 07:32:53 -0500270
271/** @brief Reads IM Keyword from the vpd
272 * @param[in] vpdMap - parsed vpd
273 * @returns value of IM Keyword
274 */
Priyanga Ramasamye0084322022-09-27 06:28:33 -0500275const std::string getIM(const Parsed& vpdMap);
Alpana Kumarif05effd2021-04-07 07:32:53 -0500276
PriyangaRamasamy647868e2020-09-08 17:03:19 +0530277/** @brief Translate udev event generated path to a generic /sys/bus eeprom path
278 * @param[io] file - path generated from udev event.
279 */
Priyanga Ramasamye0084322022-09-27 06:28:33 -0500280void udevToGenericPath(std::string& file);
PriyangaRamasamyc2fe40f2021-03-02 06:27:33 -0600281
282/**
283 * @brief API to generate a vpd name in some pattern.
284 * This vpd-name denotes name of the bad vpd file.
285 * For i2c eeproms - the pattern of the vpd-name will be
286 * i2c-<bus-number>-<eeprom-address>. For spi eeproms - the pattern of the
287 * vpd-name will be spi-<spi-number>.
288 *
289 * @param[in] file - file path of the vpd
290 * @return the vpd-name.
291 */
Priyanga Ramasamye0084322022-09-27 06:28:33 -0500292std::string getBadVpdName(const std::string& file);
PriyangaRamasamyc2fe40f2021-03-02 06:27:33 -0600293
294/**
295 * @brief API which dumps the broken/bad vpd in a directory
296 * When the vpd is bad, this api places the bad vpd file inside
297 * "/tmp/bad-vpd" in BMC, in order to collect bad VPD data as a part of user
298 * initiated BMC dump.
299 *
300 * @param[in] file - bad vpd file path
301 * @param[in] vpdVector - bad vpd vector
302 */
303void dumpBadVpd(const std::string& file, const Binary& vpdVector);
alpana077ce68722021-07-25 13:23:59 -0500304
305/*
306 * @brief This function fetches the value for given keyword in the given record
307 * from vpd data and returns this value.
308 *
309 * @param[in] vpdMap - vpd to find out the data
310 * @param[in] rec - Record under which desired keyword exists
311 * @param[in] kwd - keyword to read the data from
312 *
313 * @returns keyword value if record/keyword combination found
314 * empty string if record or keyword is not found.
315 */
Priyanga Ramasamye0084322022-09-27 06:28:33 -0500316const std::string getKwVal(const Parsed& vpdMap, const std::string& rec,
317 const std::string& kwd);
alpana077ce68722021-07-25 13:23:59 -0500318
Alpana Kumarib17dd3b2020-10-01 00:18:10 -0500319/** @brief This creates a complete command using all it's input parameters,
320 * to bind or unbind the driver.
321 * @param[in] devNameAddr - device address on that bus
322 * @param[in] busType - i2c, spi
323 * @param[in] driverType - type of driver like at24
324 * @param[in] bindOrUnbind - either bind or unbind
325 * @returns Command to bind or unbind the driver.
326 */
Priyanga Ramasamye0084322022-09-27 06:28:33 -0500327inline std::string createBindUnbindDriverCmnd(const std::string& devNameAddr,
328 const std::string& busType,
329 const std::string& driverType,
330 const std::string& bindOrUnbind)
Alpana Kumarib17dd3b2020-10-01 00:18:10 -0500331{
332 return ("echo " + devNameAddr + " > /sys/bus/" + busType + "/drivers/" +
333 driverType + "/" + bindOrUnbind);
334}
335
Priyanga Ramasamy02434932021-10-07 16:26:05 -0500336/**
337 * @brief Get Printable Value
338 *
339 * Checks if the vector value has non printable characters.
340 * Returns hex value if non printable char is found else
341 * returns ascii value.
342 *
343 * @param[in] vector - Reference of the Binary vector
344 * @return printable value - either in hex or in ascii.
345 */
Priyanga Ramasamye0084322022-09-27 06:28:33 -0500346std::string getPrintableValue(const Binary& vec);
Priyanga Ramasamyc9ecf8e2021-10-08 02:28:52 -0500347
348/**
349 * @brief Convert byte array to hex string.
350 * @param[in] vec - byte array
351 * @return hexadecimal string of bytes.
352 */
Priyanga Ramasamye0084322022-09-27 06:28:33 -0500353std::string byteArrayToHexString(const Binary& vec);
Priyanga Ramasamy02434932021-10-07 16:26:05 -0500354
Priyanga Ramasamyaa8a8932022-01-27 09:12:41 -0600355/**
Santosh Puranik53b38ed2022-04-10 23:15:22 +0530356 * @brief Return presence of the FRU.
357 *
358 * This API returns the presence information of the FRU corresponding to the
359 * given EEPROM. If the JSON contains no information about presence detect, this
360 * will return an empty optional. Else it will get the presence GPIO information
361 * from the JSON and return the appropriate present status.
362 * In case of GPIO find/read errors, it will return false.
363 *
364 * @param[in] json - The VPD JSON
365 * @param[in] file - EEPROM file path
366 * @return Empty optional if there is no presence info. Else returns presence
367 * based on the GPIO read.
368 */
Priyanga Ramasamye0084322022-09-27 06:28:33 -0500369std::optional<bool> isPresent(const nlohmann::json& json,
370 const std::string& file);
Santosh Puranik53b38ed2022-04-10 23:15:22 +0530371
372/**
373 * @brief Performs any pre-action needed to get the FRU setup for
374 * collection.
Alpana Kumari735dee92022-03-25 01:24:40 -0500375 *
376 * @param[in] json - json object
377 * @param[in] file - eeprom file path
378 * @return - success or failure
379 */
Priyanga Ramasamye0084322022-09-27 06:28:33 -0500380bool executePreAction(const nlohmann::json& json, const std::string& file);
Alpana Kumari735dee92022-03-25 01:24:40 -0500381
382/**
383 * @brief This API will be called at the end of VPD collection to perform any
384 * post actions.
385 *
386 * @param[in] json - json object
387 * @param[in] file - eeprom file path
388 */
Priyanga Ramasamye0084322022-09-27 06:28:33 -0500389void executePostFailAction(const nlohmann::json& json, const std::string& file);
Alpana Kumari735dee92022-03-25 01:24:40 -0500390
391/**
Priyanga Ramasamyaa8a8932022-01-27 09:12:41 -0600392 * @brief Helper function to insert or merge in map.
393 *
394 * This method checks in the given inventory::InterfaceMap if the given
395 * interface key is existing or not. If the interface key already exists, given
396 * property map is inserted into it. If the key does'nt exist then given
397 * interface and property map pair is newly created. If the property present in
398 * propertymap already exist in the InterfaceMap, then the new property value is
399 * ignored.
400 *
401 * @param[in,out] map - map object of type inventory::InterfaceMap only.
402 * @param[in] interface - Interface name.
403 * @param[in] property - new property map that needs to be emplaced.
404 */
405void insertOrMerge(inventory::InterfaceMap& map,
406 const inventory::Interface& interface,
407 inventory::PropertyMap&& property);
408
Santosh Puranikf2d3b532022-04-19 06:44:07 -0500409/**
410 * @brief Utility API to set a D-Bus property
411 *
412 * This calls org.freedesktop.DBus.Properties;Set method with the supplied
413 * arguments
414 *
415 * @tparam T Template type of the D-Bus property
416 * @param service[in] - The D-Bus service name.
417 * @param object[in] - The D-Bus object on which the property is to be set.
418 * @param interface[in] - The D-Bus interface to which the property belongs.
419 * @param propertyName[in] - The name of the property to set.
420 * @param propertyValue[in] - The value of the property.
421 */
422template <typename T>
423void setBusProperty(const std::string& service, const std::string& object,
424 const std::string& interface,
425 const std::string& propertyName,
426 const std::variant<T>& propertyValue)
427{
428 try
429 {
430 auto bus = sdbusplus::bus::new_default();
431 auto method =
432 bus.new_method_call(service.c_str(), object.c_str(),
433 "org.freedesktop.DBus.Properties", "Set");
434 method.append(interface);
435 method.append(propertyName);
436 method.append(propertyValue);
437
438 bus.call(method);
439 }
440 catch (const sdbusplus::exception::SdBusError& e)
441 {
442 std::cerr << e.what() << std::endl;
443 }
444}
445
446/**
447 * @brief Reads BIOS Attribute by name.
448 *
449 * @param attrName[in] - The BIOS attribute name.
450 * @return std::variant<int64_t, std::string> - The BIOS attribute value.
451 */
452std::variant<int64_t, std::string>
453 readBIOSAttribute(const std::string& attrName);
Priyanga Ramasamy335873f2022-05-18 01:31:54 -0500454
455/**
456 * @brief Returns the power state for chassis0
457 * @return The chassis power state.
458 */
459std::string getPowerState();
Santosh Puranik6b2b5372022-06-02 20:49:02 +0530460
461/**
462 * @brief Reads VPD from the supplied EEPROM
463 *
464 * This function reads the given VPD EEPROM file and returns its contents as a
465 * byte array. It handles any offsets into the file that need to be taken care
466 * of by looking up the VPD JSON for a possible offset key.
467 *
468 * @param js[in] - The VPD JSON Object
469 * @param file[in] - The path to the EEPROM to read
470 * @return A byte array containing the raw VPD.
471 */
472Binary getVpdDataInVector(const nlohmann::json& js, const std::string& file);
Patrick Venturec83c4dc2018-11-01 16:29:18 -0700473} // namespace vpd
Santosh Puranikf2d3b532022-04-19 06:44:07 -0500474} // namespace openpower