From 0acf057f9ed774ca7c354fc5735d53c6f53a8cef Mon Sep 17 00:00:00 2001 From: Marri Devender Rao Date: Mon, 3 Jul 2017 12:25:47 -0500 Subject: read data for the specified FRU id from inventory Change-Id: I5255541719edad6453cd3163d9ad428548f1a2c7 Signed-off-by: Marri Devender Rao --- read_fru_data.cpp | 118 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 118 insertions(+) create mode 100644 read_fru_data.cpp (limited to 'read_fru_data.cpp') diff --git a/read_fru_data.cpp b/read_fru_data.cpp new file mode 100644 index 0000000..5388926 --- /dev/null +++ b/read_fru_data.cpp @@ -0,0 +1,118 @@ +#include +#include +#include "xyz/openbmc_project/Common/error.hpp" +#include "read_fru_data.hpp" +#include "fruread.hpp" +#include "host-ipmid/ipmid-api.h" +#include "utils.hpp" + +extern const FruMap frus; + +namespace ipmi +{ +namespace fru +{ +using namespace phosphor::logging; +using InternalFailure = + sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure; + +static constexpr auto INV_INTF = "xyz.openbmc_project.Inventory.Manager"; +static constexpr auto OBJ_PATH = "/xyz/openbmc_project/inventory"; +static constexpr auto PROP_INTF = "org.freedesktop.DBus.Properties"; + +namespace cache +{ + //User initiate read FRU info area command followed by + //FRU read command. Also data is read in small chunks of + //the specified offset and count. + //Caching the data which will be invalidated when ever there + //is a change in FRU properties. + FRUAreaMap fruMap; +} +/** + * @brief Read the property value from Inventory + * + * @param[in] bus dbus + * @param[in] intf Interface + * @param[in] propertyName Name of the property + * @param[in] path Object path + * @return property value + */ +std::string readProperty(const std::string& intf, + const std::string& propertyName, + const std::string& path) +{ + sdbusplus::bus::bus bus{ipmid_get_sd_bus_connection()}; + auto service = ipmi::getService(bus, INV_INTF, OBJ_PATH); + std::string objPath = OBJ_PATH + path; + auto method = bus.new_method_call(service.c_str(), + objPath.c_str(), + PROP_INTF, + "Get"); + method.append(intf, propertyName); + auto reply = bus.call(method); + if (reply.is_method_error()) + { + //If property is not found simply return empty value + log("Property value not set", + entry("Property=%s", propertyName), + entry("Path=%s", objPath)); + return {}; + } + sdbusplus::message::variant property; + reply.read(property); + std::string value = + sdbusplus::message::variant_ns::get(property); + return value; +} + +/** + * @brief Read FRU property values from Inventory + * + * @param[in] fruNum FRU id + * @return populate FRU Inventory data + */ +FruInventoryData readDataFromInventory(const FRUId& fruNum) +{ + auto iter = frus.find(fruNum); + if (iter == frus.end()) + { + log("Unsupported FRU ID ",entry("FRUID=%d", fruNum)); + elog(); + } + + FruInventoryData data; + auto& instanceList = iter->second; + for (auto& instance : instanceList) + { + for (auto& interfaceList : instance.second) + { + for (auto& properties : interfaceList.second) + { + decltype(auto) pdata = properties.second; + auto value = readProperty( + interfaceList.first, properties.first, + instance.first); + data[pdata.section].emplace(properties.first, value); + } + } + } + return data; +} + +const FruAreaData& getFruAreaData(const FRUId& fruNum) +{ + auto iter = cache::fruMap.find(fruNum); + if (iter != cache::fruMap.end()) + { + return iter->second; + } + auto invData = readDataFromInventory(fruNum); + + //Build area info based on inventory data + FruAreaData newdata = buildFruAreaData(std::move(invData)); + cache::fruMap.emplace(fruNum, std::move(newdata)); + return cache::fruMap.at(fruNum); +} +} //fru +} //ipmi -- cgit v1.2.1